ccxt 4.2.11 → 4.2.12

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 (375) hide show
  1. package/README.md +5 -5
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +640 -261
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/_virtual/agent.js +7 -0
  6. package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
  7. package/dist/cjs/_virtual/promisify.js +7 -0
  8. package/dist/cjs/ccxt.js +1 -1
  9. package/dist/cjs/js/ccxt.js +474 -0
  10. package/dist/cjs/js/src/abstract/ace.js +9 -0
  11. package/dist/cjs/js/src/abstract/alpaca.js +9 -0
  12. package/dist/cjs/js/src/abstract/ascendex.js +9 -0
  13. package/dist/cjs/js/src/abstract/bigone.js +9 -0
  14. package/dist/cjs/js/src/abstract/binance.js +9 -0
  15. package/dist/cjs/js/src/abstract/bingx.js +9 -0
  16. package/dist/cjs/js/src/abstract/bit2c.js +9 -0
  17. package/dist/cjs/js/src/abstract/bitbank.js +9 -0
  18. package/dist/cjs/js/src/abstract/bitbns.js +9 -0
  19. package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
  20. package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
  21. package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
  22. package/dist/cjs/js/src/abstract/bitforex.js +9 -0
  23. package/dist/cjs/js/src/abstract/bitget.js +9 -0
  24. package/dist/cjs/js/src/abstract/bithumb.js +9 -0
  25. package/dist/cjs/js/src/abstract/bitmart.js +9 -0
  26. package/dist/cjs/js/src/abstract/bitmex.js +9 -0
  27. package/dist/cjs/js/src/abstract/bitopro.js +9 -0
  28. package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
  29. package/dist/cjs/js/src/abstract/bitrue.js +9 -0
  30. package/dist/cjs/js/src/abstract/bitso.js +9 -0
  31. package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
  32. package/dist/cjs/js/src/abstract/bitteam.js +9 -0
  33. package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
  34. package/dist/cjs/js/src/abstract/bl3p.js +9 -0
  35. package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
  36. package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
  37. package/dist/cjs/js/src/abstract/btcbox.js +9 -0
  38. package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
  39. package/dist/cjs/js/src/abstract/btcturk.js +9 -0
  40. package/dist/cjs/js/src/abstract/bybit.js +9 -0
  41. package/dist/cjs/js/src/abstract/cex.js +9 -0
  42. package/dist/cjs/js/src/abstract/coinbase.js +9 -0
  43. package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
  44. package/dist/cjs/js/src/abstract/coincheck.js +9 -0
  45. package/dist/cjs/js/src/abstract/coinex.js +9 -0
  46. package/dist/cjs/js/src/abstract/coinlist.js +9 -0
  47. package/dist/cjs/js/src/abstract/coinmate.js +9 -0
  48. package/dist/cjs/js/src/abstract/coinone.js +9 -0
  49. package/dist/cjs/js/src/abstract/coinsph.js +9 -0
  50. package/dist/cjs/js/src/abstract/coinspot.js +9 -0
  51. package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
  52. package/dist/cjs/js/src/abstract/currencycom.js +9 -0
  53. package/dist/cjs/js/src/abstract/delta.js +9 -0
  54. package/dist/cjs/js/src/abstract/deribit.js +9 -0
  55. package/dist/cjs/js/src/abstract/digifinex.js +9 -0
  56. package/dist/cjs/js/src/abstract/exmo.js +9 -0
  57. package/dist/cjs/js/src/abstract/gate.js +9 -0
  58. package/dist/cjs/js/src/abstract/gemini.js +9 -0
  59. package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
  60. package/dist/cjs/js/src/abstract/hollaex.js +9 -0
  61. package/dist/cjs/js/src/abstract/htx.js +9 -0
  62. package/dist/cjs/js/src/abstract/huobijp.js +9 -0
  63. package/dist/cjs/js/src/abstract/idex.js +9 -0
  64. package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
  65. package/dist/cjs/js/src/abstract/indodax.js +9 -0
  66. package/dist/cjs/js/src/abstract/kraken.js +9 -0
  67. package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
  68. package/dist/cjs/js/src/abstract/kucoin.js +9 -0
  69. package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
  70. package/dist/cjs/js/src/abstract/kuna.js +9 -0
  71. package/dist/cjs/js/src/abstract/latoken.js +9 -0
  72. package/dist/cjs/js/src/abstract/lbank.js +9 -0
  73. package/dist/cjs/js/src/abstract/luno.js +9 -0
  74. package/dist/cjs/js/src/abstract/lykke.js +9 -0
  75. package/dist/cjs/js/src/abstract/mercado.js +9 -0
  76. package/dist/cjs/js/src/abstract/mexc.js +9 -0
  77. package/dist/cjs/js/src/abstract/ndax.js +9 -0
  78. package/dist/cjs/js/src/abstract/novadax.js +9 -0
  79. package/dist/cjs/js/src/abstract/oceanex.js +9 -0
  80. package/dist/cjs/js/src/abstract/okcoin.js +9 -0
  81. package/dist/cjs/js/src/abstract/okx.js +9 -0
  82. package/dist/cjs/js/src/abstract/p2b.js +9 -0
  83. package/dist/cjs/js/src/abstract/paymium.js +9 -0
  84. package/dist/cjs/js/src/abstract/phemex.js +9 -0
  85. package/dist/cjs/js/src/abstract/poloniex.js +9 -0
  86. package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
  87. package/dist/cjs/js/src/abstract/probit.js +9 -0
  88. package/dist/cjs/js/src/abstract/timex.js +9 -0
  89. package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
  90. package/dist/cjs/js/src/abstract/upbit.js +9 -0
  91. package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
  92. package/dist/cjs/js/src/abstract/wazirx.js +9 -0
  93. package/dist/cjs/js/src/abstract/whitebit.js +9 -0
  94. package/dist/cjs/js/src/abstract/woo.js +9 -0
  95. package/dist/cjs/js/src/abstract/yobit.js +9 -0
  96. package/dist/cjs/js/src/abstract/zaif.js +9 -0
  97. package/dist/cjs/js/src/abstract/zonda.js +9 -0
  98. package/dist/cjs/js/src/ace.js +1058 -0
  99. package/dist/cjs/js/src/alpaca.js +1125 -0
  100. package/dist/cjs/js/src/ascendex.js +3360 -0
  101. package/dist/cjs/js/src/base/Exchange.js +5110 -0
  102. package/dist/cjs/js/src/base/Precise.js +263 -0
  103. package/dist/cjs/js/src/base/errors.js +299 -0
  104. package/dist/cjs/js/src/base/functions/crypto.js +78 -0
  105. package/dist/cjs/js/src/base/functions/encode.js +44 -0
  106. package/dist/cjs/js/src/base/functions/generic.js +193 -0
  107. package/dist/cjs/js/src/base/functions/misc.js +96 -0
  108. package/dist/cjs/js/src/base/functions/number.js +297 -0
  109. package/dist/cjs/js/src/base/functions/platform.js +28 -0
  110. package/dist/cjs/js/src/base/functions/rsa.js +34 -0
  111. package/dist/cjs/js/src/base/functions/string.js +48 -0
  112. package/dist/cjs/js/src/base/functions/throttle.js +66 -0
  113. package/dist/cjs/js/src/base/functions/time.js +187 -0
  114. package/dist/cjs/js/src/base/functions/totp.js +24 -0
  115. package/dist/cjs/js/src/base/functions/type.js +162 -0
  116. package/dist/cjs/js/src/base/functions.js +157 -0
  117. package/dist/cjs/js/src/base/ws/Cache.js +254 -0
  118. package/dist/cjs/js/src/base/ws/Client.js +299 -0
  119. package/dist/cjs/js/src/base/ws/Future.js +34 -0
  120. package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
  121. package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
  122. package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
  123. package/dist/cjs/js/src/bequant.js +33 -0
  124. package/dist/cjs/js/src/bigone.js +2142 -0
  125. package/dist/cjs/js/src/binance.js +9729 -0
  126. package/dist/cjs/js/src/binancecoinm.js +45 -0
  127. package/dist/cjs/js/src/binanceus.js +84 -0
  128. package/dist/cjs/js/src/binanceusdm.js +58 -0
  129. package/dist/cjs/js/src/bingx.js +3737 -0
  130. package/dist/cjs/js/src/bit2c.js +916 -0
  131. package/dist/cjs/js/src/bitbank.js +1000 -0
  132. package/dist/cjs/js/src/bitbay.js +17 -0
  133. package/dist/cjs/js/src/bitbns.js +1220 -0
  134. package/dist/cjs/js/src/bitcoincom.js +17 -0
  135. package/dist/cjs/js/src/bitfinex.js +1670 -0
  136. package/dist/cjs/js/src/bitfinex2.js +2990 -0
  137. package/dist/cjs/js/src/bitflyer.js +1045 -0
  138. package/dist/cjs/js/src/bitforex.js +852 -0
  139. package/dist/cjs/js/src/bitget.js +8284 -0
  140. package/dist/cjs/js/src/bithumb.js +1090 -0
  141. package/dist/cjs/js/src/bitmart.js +4454 -0
  142. package/dist/cjs/js/src/bitmex.js +2884 -0
  143. package/dist/cjs/js/src/bitopro.js +1724 -0
  144. package/dist/cjs/js/src/bitpanda.js +2002 -0
  145. package/dist/cjs/js/src/bitrue.js +3253 -0
  146. package/dist/cjs/js/src/bitso.js +1753 -0
  147. package/dist/cjs/js/src/bitstamp.js +2188 -0
  148. package/dist/cjs/js/src/bitteam.js +2309 -0
  149. package/dist/cjs/js/src/bitvavo.js +1968 -0
  150. package/dist/cjs/js/src/bl3p.js +447 -0
  151. package/dist/cjs/js/src/blockchaincom.js +1160 -0
  152. package/dist/cjs/js/src/btcalpha.js +929 -0
  153. package/dist/cjs/js/src/btcbox.js +565 -0
  154. package/dist/cjs/js/src/btcmarkets.js +1237 -0
  155. package/dist/cjs/js/src/btcturk.js +929 -0
  156. package/dist/cjs/js/src/bybit.js +7646 -0
  157. package/dist/cjs/js/src/cex.js +1693 -0
  158. package/dist/cjs/js/src/coinbase.js +3274 -0
  159. package/dist/cjs/js/src/coinbasepro.js +1866 -0
  160. package/dist/cjs/js/src/coincheck.js +843 -0
  161. package/dist/cjs/js/src/coinex.js +5414 -0
  162. package/dist/cjs/js/src/coinlist.js +2329 -0
  163. package/dist/cjs/js/src/coinmate.js +989 -0
  164. package/dist/cjs/js/src/coinone.js +1185 -0
  165. package/dist/cjs/js/src/coinsph.js +1933 -0
  166. package/dist/cjs/js/src/coinspot.js +548 -0
  167. package/dist/cjs/js/src/cryptocom.js +3007 -0
  168. package/dist/cjs/js/src/currencycom.js +2015 -0
  169. package/dist/cjs/js/src/delta.js +3256 -0
  170. package/dist/cjs/js/src/deribit.js +3306 -0
  171. package/dist/cjs/js/src/digifinex.js +4307 -0
  172. package/dist/cjs/js/src/exmo.js +2645 -0
  173. package/dist/cjs/js/src/fmfwio.js +34 -0
  174. package/dist/cjs/js/src/gate.js +7054 -0
  175. package/dist/cjs/js/src/gateio.js +16 -0
  176. package/dist/cjs/js/src/gemini.js +1801 -0
  177. package/dist/cjs/js/src/hitbtc.js +3660 -0
  178. package/dist/cjs/js/src/hitbtc3.js +19 -0
  179. package/dist/cjs/js/src/hollaex.js +1882 -0
  180. package/dist/cjs/js/src/htx.js +9024 -0
  181. package/dist/cjs/js/src/huobi.js +16 -0
  182. package/dist/cjs/js/src/huobijp.js +1918 -0
  183. package/dist/cjs/js/src/idex.js +1770 -0
  184. package/dist/cjs/js/src/independentreserve.js +759 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2861 -0
  187. package/dist/cjs/js/src/krakenfutures.js +2407 -0
  188. package/dist/cjs/js/src/kucoin.js +4489 -0
  189. package/dist/cjs/js/src/kucoinfutures.js +2475 -0
  190. package/dist/cjs/js/src/kuna.js +1949 -0
  191. package/dist/cjs/js/src/latoken.js +1729 -0
  192. package/dist/cjs/js/src/lbank.js +2825 -0
  193. package/dist/cjs/js/src/luno.js +1044 -0
  194. package/dist/cjs/js/src/lykke.js +1303 -0
  195. package/dist/cjs/js/src/mercado.js +897 -0
  196. package/dist/cjs/js/src/mexc.js +5407 -0
  197. package/dist/cjs/js/src/ndax.js +2450 -0
  198. package/dist/cjs/js/src/novadax.js +1556 -0
  199. package/dist/cjs/js/src/oceanex.js +964 -0
  200. package/dist/cjs/js/src/okcoin.js +3115 -0
  201. package/dist/cjs/js/src/okx.js +7329 -0
  202. package/dist/cjs/js/src/p2b.js +1243 -0
  203. package/dist/cjs/js/src/paymium.js +597 -0
  204. package/dist/cjs/js/src/phemex.js +4715 -0
  205. package/dist/cjs/js/src/poloniex.js +2356 -0
  206. package/dist/cjs/js/src/poloniexfutures.js +1794 -0
  207. package/dist/cjs/js/src/pro/alpaca.js +714 -0
  208. package/dist/cjs/js/src/pro/ascendex.js +957 -0
  209. package/dist/cjs/js/src/pro/bequant.js +33 -0
  210. package/dist/cjs/js/src/pro/binance.js +2796 -0
  211. package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
  212. package/dist/cjs/js/src/pro/binanceus.js +51 -0
  213. package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
  214. package/dist/cjs/js/src/pro/bingx.js +944 -0
  215. package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
  216. package/dist/cjs/js/src/pro/bitfinex.js +672 -0
  217. package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
  218. package/dist/cjs/js/src/pro/bitget.js +1733 -0
  219. package/dist/cjs/js/src/pro/bitmart.js +1486 -0
  220. package/dist/cjs/js/src/pro/bitmex.js +1576 -0
  221. package/dist/cjs/js/src/pro/bitopro.js +327 -0
  222. package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
  223. package/dist/cjs/js/src/pro/bitrue.js +462 -0
  224. package/dist/cjs/js/src/pro/bitstamp.js +547 -0
  225. package/dist/cjs/js/src/pro/bitvavo.js +704 -0
  226. package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
  227. package/dist/cjs/js/src/pro/bybit.js +1843 -0
  228. package/dist/cjs/js/src/pro/cex.js +1510 -0
  229. package/dist/cjs/js/src/pro/coinbase.js +561 -0
  230. package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
  231. package/dist/cjs/js/src/pro/coinex.js +1095 -0
  232. package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
  233. package/dist/cjs/js/src/pro/currencycom.js +563 -0
  234. package/dist/cjs/js/src/pro/deribit.js +825 -0
  235. package/dist/cjs/js/src/pro/exmo.js +658 -0
  236. package/dist/cjs/js/src/pro/gate.js +1316 -0
  237. package/dist/cjs/js/src/pro/gateio.js +16 -0
  238. package/dist/cjs/js/src/pro/gemini.js +649 -0
  239. package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
  240. package/dist/cjs/js/src/pro/hollaex.js +597 -0
  241. package/dist/cjs/js/src/pro/htx.js +2383 -0
  242. package/dist/cjs/js/src/pro/huobi.js +16 -0
  243. package/dist/cjs/js/src/pro/huobijp.js +606 -0
  244. package/dist/cjs/js/src/pro/idex.js +714 -0
  245. package/dist/cjs/js/src/pro/independentreserve.js +280 -0
  246. package/dist/cjs/js/src/pro/kraken.js +1364 -0
  247. package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
  248. package/dist/cjs/js/src/pro/kucoin.js +1052 -0
  249. package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
  250. package/dist/cjs/js/src/pro/luno.js +322 -0
  251. package/dist/cjs/js/src/pro/mexc.js +1170 -0
  252. package/dist/cjs/js/src/pro/ndax.js +545 -0
  253. package/dist/cjs/js/src/pro/okcoin.js +760 -0
  254. package/dist/cjs/js/src/pro/okx.js +1558 -0
  255. package/dist/cjs/js/src/pro/phemex.js +1511 -0
  256. package/dist/cjs/js/src/pro/poloniex.js +1253 -0
  257. package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
  258. package/dist/cjs/js/src/pro/probit.js +586 -0
  259. package/dist/cjs/js/src/pro/upbit.js +234 -0
  260. package/dist/cjs/js/src/pro/wazirx.js +776 -0
  261. package/dist/cjs/js/src/pro/whitebit.js +927 -0
  262. package/dist/cjs/js/src/pro/woo.js +769 -0
  263. package/dist/cjs/js/src/probit.js +1865 -0
  264. package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
  265. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
  266. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
  267. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
  268. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
  269. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
  270. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
  271. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
  272. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
  273. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
  274. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
  275. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
  276. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
  277. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
  278. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
  279. package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
  280. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
  281. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
  282. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
  283. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
  284. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
  285. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
  286. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
  287. package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
  288. package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
  289. package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
  290. package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
  291. package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
  292. package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
  293. package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
  294. package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
  295. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
  296. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
  297. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
  298. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
  299. package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
  300. package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
  301. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
  302. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
  303. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
  304. package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
  305. package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
  306. package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
  307. package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
  308. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
  309. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
  310. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
  311. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
  312. package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
  313. package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
  314. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
  315. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
  316. package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
  317. package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
  318. package/dist/cjs/js/src/timex.js +1562 -0
  319. package/dist/cjs/js/src/tokocrypto.js +2542 -0
  320. package/dist/cjs/js/src/upbit.js +1844 -0
  321. package/dist/cjs/js/src/wavesexchange.js +2607 -0
  322. package/dist/cjs/js/src/wazirx.js +953 -0
  323. package/dist/cjs/js/src/whitebit.js +2309 -0
  324. package/dist/cjs/js/src/woo.js +2715 -0
  325. package/dist/cjs/js/src/yobit.js +1314 -0
  326. package/dist/cjs/js/src/zaif.js +736 -0
  327. package/dist/cjs/js/src/zonda.js +1883 -0
  328. package/js/ccxt.d.ts +1 -1
  329. package/js/ccxt.js +1 -1
  330. package/js/src/abstract/bigone.d.ts +18 -0
  331. package/js/src/abstract/binance.d.ts +2 -0
  332. package/js/src/abstract/binancecoinm.d.ts +2 -0
  333. package/js/src/abstract/binanceus.d.ts +2 -0
  334. package/js/src/abstract/binanceusdm.d.ts +2 -0
  335. package/js/src/abstract/bybit.d.ts +1 -0
  336. package/js/src/abstract/gate.d.ts +11 -0
  337. package/js/src/abstract/gateio.d.ts +11 -0
  338. package/js/src/alpaca.js +18 -18
  339. package/js/src/base/Exchange.d.ts +5 -1
  340. package/js/src/base/Exchange.js +101 -12
  341. package/js/src/bigone.d.ts +1 -2
  342. package/js/src/bigone.js +340 -145
  343. package/js/src/binance.js +15 -8
  344. package/js/src/bingx.js +9 -2
  345. package/js/src/bitfinex.d.ts +2 -2
  346. package/js/src/bitfinex.js +2 -3
  347. package/js/src/bitget.js +21 -8
  348. package/js/src/bitmart.d.ts +2 -2
  349. package/js/src/bitmart.js +3 -3
  350. package/js/src/bitmex.js +1 -0
  351. package/js/src/bybit.js +2 -0
  352. package/js/src/coinlist.js +2 -3
  353. package/js/src/coinsph.js +2 -3
  354. package/js/src/deribit.js +1 -0
  355. package/js/src/gate.d.ts +4 -4
  356. package/js/src/gate.js +22 -3
  357. package/js/src/hitbtc.d.ts +4 -4
  358. package/js/src/hitbtc.js +2 -3
  359. package/js/src/htx.js +4 -7
  360. package/js/src/huobijp.js +2 -3
  361. package/js/src/kraken.js +1 -0
  362. package/js/src/mexc.js +2 -1
  363. package/js/src/okx.js +13 -3
  364. package/js/src/pro/binance.d.ts +2 -23
  365. package/js/src/pro/binance.js +58 -22
  366. package/js/src/pro/coinbase.d.ts +2 -2
  367. package/js/src/pro/coinbase.js +4 -1
  368. package/js/src/pro/coinbasepro.d.ts +2 -2
  369. package/js/src/pro/hitbtc.d.ts +2 -2
  370. package/js/src/pro/poloniex.d.ts +2 -2
  371. package/js/src/upbit.d.ts +3 -101
  372. package/js/src/upbit.js +12 -12
  373. package/js/src/woo.js +2 -0
  374. package/package.json +1 -1
  375. package/skip-tests.json +5 -0
@@ -0,0 +1,3737 @@
1
+ 'use strict';
2
+
3
+ var bingx$1 = require('./abstract/bingx.js');
4
+ var errors = require('./base/errors.js');
5
+ var Precise = require('./base/Precise.js');
6
+ var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
7
+ var number = require('./base/functions/number.js');
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // ---------------------------------------------------------------------------
11
+ class bingx extends bingx$1 {
12
+ describe() {
13
+ return this.deepExtend(super.describe(), {
14
+ 'id': 'bingx',
15
+ 'name': 'BingX',
16
+ 'countries': ['US'],
17
+ // cheapest is 60 requests a minute = 1 requests per second on average => ( 1000ms / 1) = 1000 ms between requests on average
18
+ 'rateLimit': 1000,
19
+ 'version': 'v1',
20
+ 'certified': true,
21
+ 'pro': true,
22
+ 'has': {
23
+ 'CORS': undefined,
24
+ 'spot': true,
25
+ 'margin': true,
26
+ 'swap': true,
27
+ 'future': false,
28
+ 'option': false,
29
+ 'cancelAllOrders': true,
30
+ 'cancelOrder': true,
31
+ 'cancelOrders': true,
32
+ 'closeAllPositions': true,
33
+ 'closePosition': true,
34
+ 'createMarketBuyOrderWithCost': true,
35
+ 'createMarketOrderWithCost': true,
36
+ 'createMarketSellOrderWithCost': true,
37
+ 'createOrder': true,
38
+ 'createOrders': true,
39
+ 'createTrailingAmountOrder': true,
40
+ 'createTrailingPercentOrder': true,
41
+ 'fetchBalance': true,
42
+ 'fetchClosedOrders': true,
43
+ 'fetchCurrencies': true,
44
+ 'fetchDepositAddress': true,
45
+ 'fetchDeposits': true,
46
+ 'fetchDepositWithdrawFee': 'emulated',
47
+ 'fetchDepositWithdrawFees': true,
48
+ 'fetchFundingRate': true,
49
+ 'fetchFundingRateHistory': true,
50
+ 'fetchLeverage': true,
51
+ 'fetchLiquidations': false,
52
+ 'fetchMarkets': true,
53
+ 'fetchMyLiquidations': true,
54
+ 'fetchOHLCV': true,
55
+ 'fetchOpenInterest': true,
56
+ 'fetchOpenOrders': true,
57
+ 'fetchOrder': true,
58
+ 'fetchOrderBook': true,
59
+ 'fetchPositions': true,
60
+ 'fetchTicker': true,
61
+ 'fetchTickers': true,
62
+ 'fetchTime': true,
63
+ 'fetchTrades': true,
64
+ 'fetchTransfers': true,
65
+ 'fetchWithdrawals': true,
66
+ 'setLeverage': true,
67
+ 'setMargin': true,
68
+ 'setMarginMode': true,
69
+ 'transfer': true,
70
+ },
71
+ 'hostname': 'bingx.com',
72
+ 'urls': {
73
+ 'logo': 'https://github-production-user-asset-6210df.s3.amazonaws.com/1294454/253675376-6983b72e-4999-4549-b177-33b374c195e3.jpg',
74
+ 'api': {
75
+ 'spot': 'https://open-api.{hostname}/openApi',
76
+ 'swap': 'https://open-api.{hostname}/openApi',
77
+ 'contract': 'https://open-api.{hostname}/openApi',
78
+ 'wallets': 'https://open-api.{hostname}/openApi',
79
+ 'user': 'https://open-api.{hostname}/openApi',
80
+ 'subAccount': 'https://open-api.{hostname}/openApi',
81
+ 'account': 'https://open-api.{hostname}/openApi',
82
+ 'copyTrading': 'https://open-api.{hostname}/openApi',
83
+ },
84
+ 'www': 'https://bingx.com/',
85
+ 'doc': 'https://bingx-api.github.io/docs/',
86
+ 'referral': 'https://bingx.com/invite/OHETOM',
87
+ },
88
+ 'fees': {
89
+ 'tierBased': true,
90
+ 'spot': {
91
+ 'feeSide': 'get',
92
+ 'maker': this.parseNumber('0.001'),
93
+ 'taker': this.parseNumber('0.001'),
94
+ },
95
+ 'swap': {
96
+ 'feeSide': 'quote',
97
+ 'maker': this.parseNumber('0.0002'),
98
+ 'taker': this.parseNumber('0.0005'),
99
+ },
100
+ },
101
+ 'requiredCredentials': {
102
+ 'apiKey': true,
103
+ 'secret': true,
104
+ },
105
+ 'api': {
106
+ 'spot': {
107
+ 'v1': {
108
+ 'public': {
109
+ 'get': {
110
+ 'common/symbols': 3,
111
+ 'market/trades': 3,
112
+ 'market/depth': 3,
113
+ 'market/kline': 3,
114
+ 'ticker/24hr': 1,
115
+ },
116
+ },
117
+ 'private': {
118
+ 'get': {
119
+ 'trade/query': 3,
120
+ 'trade/openOrders': 3,
121
+ 'trade/historyOrders': 3,
122
+ 'user/commissionRate': 3,
123
+ 'account/balance': 3,
124
+ },
125
+ 'post': {
126
+ 'trade/order': 3,
127
+ 'trade/cancel': 3,
128
+ 'trade/batchOrders': 3,
129
+ 'trade/cancelOrders': 3,
130
+ 'trade/cancelOpenOrders': 3,
131
+ },
132
+ },
133
+ },
134
+ 'v3': {
135
+ 'private': {
136
+ 'get': {
137
+ 'get/asset/transfer': 3,
138
+ 'asset/transfer': 3,
139
+ 'capital/deposit/hisrec': 3,
140
+ 'capital/withdraw/history': 3,
141
+ },
142
+ 'post': {
143
+ 'post/asset/transfer': 3,
144
+ },
145
+ },
146
+ },
147
+ },
148
+ 'swap': {
149
+ 'v1': {
150
+ 'private': {
151
+ 'get': {
152
+ 'positionSide/dual': 1,
153
+ },
154
+ 'post': {
155
+ 'positionSide/dual': 1,
156
+ },
157
+ },
158
+ },
159
+ 'v2': {
160
+ 'public': {
161
+ 'get': {
162
+ 'server/time': 3,
163
+ 'quote/contracts': 1,
164
+ 'quote/price': 1,
165
+ 'quote/depth': 1,
166
+ 'quote/trades': 1,
167
+ 'quote/premiumIndex': 1,
168
+ 'quote/fundingRate': 1,
169
+ 'quote/klines': 1,
170
+ 'quote/openInterest': 1,
171
+ 'quote/ticker': 1,
172
+ 'quote/bookTicker': 1,
173
+ },
174
+ },
175
+ 'private': {
176
+ 'get': {
177
+ 'user/balance': 3,
178
+ 'user/positions': 3,
179
+ 'user/income': 3,
180
+ 'trade/openOrders': 3,
181
+ 'trade/order': 3,
182
+ 'trade/marginType': 3,
183
+ 'trade/leverage': 3,
184
+ 'trade/forceOrders': 3,
185
+ 'trade/allOrders': 3,
186
+ 'trade/allFillOrders': 3,
187
+ 'user/income/export': 3,
188
+ 'user/commissionRate': 3,
189
+ 'quote/bookTicker': 3,
190
+ },
191
+ 'post': {
192
+ 'trade/order': 3,
193
+ 'trade/batchOrders': 3,
194
+ 'trade/closeAllPositions': 3,
195
+ 'trade/marginType': 3,
196
+ 'trade/leverage': 3,
197
+ 'trade/positionMargin': 3,
198
+ 'trade/order/test': 3,
199
+ },
200
+ 'delete': {
201
+ 'trade/order': 3,
202
+ 'trade/batchOrders': 3,
203
+ 'trade/allOpenOrders': 3,
204
+ },
205
+ },
206
+ },
207
+ 'v3': {
208
+ 'public': {
209
+ 'get': {
210
+ 'quote/klines': 1,
211
+ },
212
+ },
213
+ },
214
+ },
215
+ 'contract': {
216
+ 'v1': {
217
+ 'private': {
218
+ 'get': {
219
+ 'allPosition': 3,
220
+ 'allOrders': 3,
221
+ 'balance': 3,
222
+ },
223
+ },
224
+ },
225
+ },
226
+ 'wallets': {
227
+ 'v1': {
228
+ 'private': {
229
+ 'get': {
230
+ 'capital/config/getall': 3,
231
+ 'capital/deposit/address': 1,
232
+ 'capital/innerTransfer/records': 1,
233
+ 'capital/subAccount/deposit/address': 1,
234
+ 'capital/deposit/subHisrec': 1,
235
+ 'capital/subAccount/innerTransfer/records': 1,
236
+ },
237
+ 'post': {
238
+ 'capital/withdraw/apply': 3,
239
+ 'capital/innerTransfer/apply': 3,
240
+ 'capital/subAccountInnerTransfer/apply': 3,
241
+ 'capital/deposit/createSubAddress': 1,
242
+ },
243
+ },
244
+ },
245
+ },
246
+ 'subAccount': {
247
+ 'v1': {
248
+ 'private': {
249
+ 'get': {
250
+ 'list': 3,
251
+ 'assets': 3,
252
+ 'apiKey/query': 1,
253
+ },
254
+ 'post': {
255
+ 'create': 3,
256
+ 'apiKey/create': 3,
257
+ 'apiKey/edit': 3,
258
+ 'apiKey/del': 3,
259
+ 'updateStatus': 3,
260
+ },
261
+ },
262
+ },
263
+ },
264
+ 'account': {
265
+ 'v1': {
266
+ 'private': {
267
+ 'get': {
268
+ 'uid': 1,
269
+ },
270
+ 'post': {
271
+ 'innerTransfer/authorizeSubAccount': 3,
272
+ },
273
+ },
274
+ },
275
+ },
276
+ 'user': {
277
+ 'auth': {
278
+ 'private': {
279
+ 'post': {
280
+ 'userDataStream': 1,
281
+ },
282
+ 'put': {
283
+ 'userDataStream': 1,
284
+ },
285
+ },
286
+ },
287
+ },
288
+ 'copyTrading': {
289
+ 'v1': {
290
+ 'private': {
291
+ 'get': {
292
+ 'swap/trace/currentTrack': 1,
293
+ },
294
+ 'post': {
295
+ 'swap/trace/closeTrackOrder': 1,
296
+ 'swap/trace/setTPSL': 1,
297
+ },
298
+ },
299
+ },
300
+ },
301
+ 'api': {
302
+ 'v3': {
303
+ 'private': {
304
+ 'get': {
305
+ 'asset/transfer': 1,
306
+ 'capital/deposit/hisrec': 1,
307
+ 'capital/withdraw/history': 1,
308
+ },
309
+ 'post': {
310
+ 'post/asset/transfer': 1,
311
+ },
312
+ },
313
+ },
314
+ },
315
+ },
316
+ 'timeframes': {
317
+ '1m': '1m',
318
+ '3m': '3m',
319
+ '5m': '5m',
320
+ '15m': '15m',
321
+ '30m': '30m',
322
+ '1h': '1h',
323
+ '2h': '2h',
324
+ '4h': '4h',
325
+ '6h': '6h',
326
+ '12h': '12h',
327
+ '1d': '1d',
328
+ '3d': '3d',
329
+ '1w': '1w',
330
+ '1M': '1M',
331
+ },
332
+ 'precisionMode': number.DECIMAL_PLACES,
333
+ 'exceptions': {
334
+ 'exact': {
335
+ '400': errors.BadRequest,
336
+ '401': errors.AuthenticationError,
337
+ '403': errors.PermissionDenied,
338
+ '404': errors.BadRequest,
339
+ '429': errors.DDoSProtection,
340
+ '418': errors.PermissionDenied,
341
+ '500': errors.ExchangeError,
342
+ '504': errors.ExchangeError,
343
+ '100001': errors.AuthenticationError,
344
+ '100412': errors.AuthenticationError,
345
+ '100202': errors.InsufficientFunds,
346
+ '100204': errors.BadRequest,
347
+ '100400': errors.BadRequest,
348
+ '100421': errors.BadSymbol,
349
+ '100440': errors.ExchangeError,
350
+ '100500': errors.ExchangeError,
351
+ '100503': errors.ExchangeError,
352
+ '80001': errors.BadRequest,
353
+ '80012': errors.ExchangeNotAvailable,
354
+ '80014': errors.BadRequest,
355
+ '80016': errors.OrderNotFound,
356
+ '80017': errors.OrderNotFound,
357
+ '100414': errors.AccountSuspended,
358
+ '100437': errors.BadRequest, // {"code":100437,"msg":"The withdrawal amount is lower than the minimum limit, please re-enter.","timestamp":1689258588845}
359
+ },
360
+ 'broad': {},
361
+ },
362
+ 'commonCurrencies': {},
363
+ 'options': {
364
+ 'defaultType': 'spot',
365
+ 'accountsByType': {
366
+ 'spot': 'FUND',
367
+ 'swap': 'PFUTURES',
368
+ 'future': 'SFUTURES',
369
+ },
370
+ 'accountsById': {
371
+ 'FUND': 'spot',
372
+ 'PFUTURES': 'swap',
373
+ 'SFUTURES': 'future',
374
+ },
375
+ 'recvWindow': 5 * 1000,
376
+ 'broker': 'CCXT',
377
+ },
378
+ });
379
+ }
380
+ async fetchTime(params = {}) {
381
+ /**
382
+ * @method
383
+ * @name bingx#fetchTime
384
+ * @description fetches the current integer timestamp in milliseconds from the bingx server
385
+ * @see https://bingx-api.github.io/docs/#/swapV2/base-info.html#Get%20Server%20Time
386
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
387
+ * @returns {int} the current integer timestamp in milliseconds from the bingx server
388
+ */
389
+ const response = await this.swapV2PublicGetServerTime(params);
390
+ //
391
+ // {
392
+ // "code": 0,
393
+ // "msg": "",
394
+ // "data": {
395
+ // "serverTime": 1675319535362
396
+ // }
397
+ // }
398
+ //
399
+ const data = this.safeValue(response, 'data');
400
+ return this.safeInteger(data, 'serverTime');
401
+ }
402
+ async fetchCurrencies(params = {}) {
403
+ /**
404
+ * @method
405
+ * @name bingx#fetchCurrencies
406
+ * @description fetches all available currencies on an exchange
407
+ * @see https://bingx-api.github.io/docs/#/common/account-api.html#All%20Coins
408
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
409
+ * @returns {object} an associative dictionary of currencies
410
+ */
411
+ if (!this.checkRequiredCredentials(false)) {
412
+ return undefined;
413
+ }
414
+ const response = await this.walletsV1PrivateGetCapitalConfigGetall(params);
415
+ //
416
+ // {
417
+ // "code": 0,
418
+ // "timestamp": 1688045966616,
419
+ // "data": [
420
+ // {
421
+ // "coin": "BTC",
422
+ // "name": "BTC",
423
+ // "networkList": [
424
+ // {
425
+ // "name": "BTC",
426
+ // "network": "BTC",
427
+ // "isDefault": true,
428
+ // "minConfirm": "2",
429
+ // "withdrawEnable": true,
430
+ // "withdrawFee": "0.00035",
431
+ // "withdrawMax": "1.62842",
432
+ // "withdrawMin": "0.0005"
433
+ // },
434
+ // {
435
+ // "name": "BTC",
436
+ // "network": "BEP20",
437
+ // "isDefault": false,
438
+ // "minConfirm": "15",
439
+ // "withdrawEnable": true,
440
+ // "withdrawFee": "0.00001",
441
+ // "withdrawMax": "1.62734",
442
+ // "withdrawMin": "0.0001"
443
+ // }
444
+ // ]
445
+ // },
446
+ // ...
447
+ // ],
448
+ // }
449
+ //
450
+ const data = this.safeValue(response, 'data', []);
451
+ const result = {};
452
+ for (let i = 0; i < data.length; i++) {
453
+ const entry = data[i];
454
+ const currencyId = this.safeString(entry, 'coin');
455
+ const code = this.safeCurrencyCode(currencyId);
456
+ const name = this.safeString(entry, 'name');
457
+ const networkList = this.safeValue(entry, 'networkList');
458
+ const networks = {};
459
+ let fee = undefined;
460
+ let active = undefined;
461
+ let withdrawEnabled = undefined;
462
+ let defaultLimits = {};
463
+ for (let j = 0; j < networkList.length; j++) {
464
+ const rawNetwork = networkList[j];
465
+ const network = this.safeString(rawNetwork, 'network');
466
+ const networkCode = this.networkIdToCode(network);
467
+ const isDefault = this.safeValue(rawNetwork, 'isDefault');
468
+ withdrawEnabled = this.safeValue(rawNetwork, 'withdrawEnable');
469
+ const limits = {
470
+ 'amounts': { 'min': this.safeNumber(rawNetwork, 'withdrawMin'), 'max': this.safeNumber(rawNetwork, 'withdrawMax') },
471
+ };
472
+ if (isDefault) {
473
+ fee = this.safeNumber(rawNetwork, 'withdrawFee');
474
+ active = withdrawEnabled;
475
+ defaultLimits = limits;
476
+ }
477
+ networks[networkCode] = {
478
+ 'info': rawNetwork,
479
+ 'id': network,
480
+ 'network': networkCode,
481
+ 'fee': fee,
482
+ 'active': active,
483
+ 'deposit': undefined,
484
+ 'withdraw': withdrawEnabled,
485
+ 'precision': undefined,
486
+ 'limits': limits,
487
+ };
488
+ }
489
+ result[code] = {
490
+ 'info': entry,
491
+ 'code': code,
492
+ 'id': currencyId,
493
+ 'precision': undefined,
494
+ 'name': name,
495
+ 'active': active,
496
+ 'deposit': undefined,
497
+ 'withdraw': withdrawEnabled,
498
+ 'networks': networks,
499
+ 'fee': fee,
500
+ 'limits': defaultLimits,
501
+ };
502
+ }
503
+ return result;
504
+ }
505
+ async fetchSpotMarkets(params) {
506
+ const response = await this.spotV1PublicGetCommonSymbols(params);
507
+ //
508
+ // {
509
+ // "code": 0,
510
+ // "msg": "",
511
+ // "debugMsg": "",
512
+ // "data": {
513
+ // "symbols": [
514
+ // {
515
+ // "symbol": "GEAR-USDT",
516
+ // "minQty": 735,
517
+ // "maxQty": 2941177,
518
+ // "minNotional": 5,
519
+ // "maxNotional": 20000,
520
+ // "status": 1,
521
+ // "tickSize": 0.000001,
522
+ // "stepSize": 1
523
+ // },
524
+ // ...
525
+ // ]
526
+ // }
527
+ // }
528
+ //
529
+ const data = this.safeValue(response, 'data');
530
+ const markets = this.safeValue(data, 'symbols', []);
531
+ return this.parseMarkets(markets);
532
+ }
533
+ async fetchSwapMarkets(params) {
534
+ const response = await this.swapV2PublicGetQuoteContracts(params);
535
+ //
536
+ // {
537
+ // "code": 0,
538
+ // "msg": "",
539
+ // "data": [
540
+ // {
541
+ // "contractId": "100",
542
+ // "symbol": "BTC-USDT",
543
+ // "size": "0.0001",
544
+ // "quantityPrecision": 4,
545
+ // "pricePrecision": 1,
546
+ // "feeRate": 0.0005,
547
+ // "tradeMinLimit": 1,
548
+ // "maxLongLeverage": 150,
549
+ // "maxShortLeverage": 150,
550
+ // "currency": "USDT",
551
+ // "asset": "BTC",
552
+ // "status": 1
553
+ // },
554
+ // ...
555
+ // ]
556
+ // }
557
+ //
558
+ const markets = this.safeValue(response, 'data', []);
559
+ return this.parseMarkets(markets);
560
+ }
561
+ parseMarket(market) {
562
+ const id = this.safeString(market, 'symbol');
563
+ const symbolParts = id.split('-');
564
+ const baseId = symbolParts[0];
565
+ const quoteId = symbolParts[1];
566
+ const base = this.safeCurrencyCode(baseId);
567
+ const quote = this.safeCurrencyCode(quoteId);
568
+ const currency = this.safeString(market, 'currency');
569
+ const settle = this.safeCurrencyCode(currency);
570
+ let pricePrecision = this.safeInteger(market, 'pricePrecision');
571
+ if (pricePrecision === undefined) {
572
+ pricePrecision = this.precisionFromString(this.safeString(market, 'tickSize'));
573
+ }
574
+ let quantityPrecision = this.safeInteger(market, 'quantityPrecision');
575
+ if (quantityPrecision === undefined) {
576
+ quantityPrecision = this.precisionFromString(this.safeString(market, 'stepSize'));
577
+ }
578
+ const type = (settle !== undefined) ? 'swap' : 'spot';
579
+ const spot = type === 'spot';
580
+ const swap = type === 'swap';
581
+ let symbol = base + '/' + quote;
582
+ if (settle !== undefined) {
583
+ symbol += ':' + settle;
584
+ }
585
+ const fees = this.safeValue(this.fees, type, {});
586
+ const contractSize = this.safeNumber(market, 'size');
587
+ const isActive = this.safeString(market, 'status') === '1';
588
+ const isInverse = (spot) ? undefined : false;
589
+ const isLinear = (spot) ? undefined : swap;
590
+ return this.safeMarketStructure({
591
+ 'id': id,
592
+ 'symbol': symbol,
593
+ 'base': base,
594
+ 'quote': quote,
595
+ 'settle': settle,
596
+ 'baseId': baseId,
597
+ 'quoteId': quoteId,
598
+ 'settleId': currency,
599
+ 'type': type,
600
+ 'spot': spot,
601
+ 'margin': false,
602
+ 'swap': swap,
603
+ 'future': false,
604
+ 'option': false,
605
+ 'active': isActive,
606
+ 'contract': swap,
607
+ 'linear': isLinear,
608
+ 'inverse': isInverse,
609
+ 'taker': this.safeNumber(fees, 'taker'),
610
+ 'maker': this.safeNumber(fees, 'maker'),
611
+ 'feeSide': this.safeString(fees, 'feeSide'),
612
+ 'contractSize': contractSize,
613
+ 'expiry': undefined,
614
+ 'expiryDatetime': undefined,
615
+ 'strike': undefined,
616
+ 'optionType': undefined,
617
+ 'precision': {
618
+ 'amount': quantityPrecision,
619
+ 'price': pricePrecision,
620
+ },
621
+ 'limits': {
622
+ 'leverage': {
623
+ 'min': undefined,
624
+ 'max': this.safeInteger(market, 'maxLongLeverage'),
625
+ },
626
+ 'amount': {
627
+ 'min': this.safeNumber(market, 'minQty'),
628
+ 'max': this.safeNumber(market, 'maxQty'),
629
+ },
630
+ 'price': {
631
+ 'min': undefined,
632
+ 'max': undefined,
633
+ },
634
+ 'cost': {
635
+ 'min': this.safeNumber(market, 'minNotional'),
636
+ 'max': this.safeNumber(market, 'maxNotional'),
637
+ },
638
+ },
639
+ 'created': undefined,
640
+ 'info': market,
641
+ });
642
+ }
643
+ async fetchMarkets(params = {}) {
644
+ /**
645
+ * @method
646
+ * @name bingx#fetchMarkets
647
+ * @description retrieves data on all markets for bingx
648
+ * @see https://bingx-api.github.io/docs/#/spot/market-api.html#Query%20Symbols
649
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Contract%20Information
650
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
651
+ * @returns {object[]} an array of objects representing market data
652
+ */
653
+ const requests = [this.fetchSpotMarkets(params), this.fetchSwapMarkets(params)];
654
+ const promises = await Promise.all(requests);
655
+ const spotMarkets = this.safeValue(promises, 0, []);
656
+ const swapMarkets = this.safeValue(promises, 1, []);
657
+ return this.arrayConcat(spotMarkets, swapMarkets);
658
+ }
659
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
660
+ /**
661
+ * @method
662
+ * @name bingx#fetchOHLCV
663
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
664
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#K-Line%20Data
665
+ * @see https://bingx-api.github.io/docs/#/spot/market-api.html#Candlestick%20chart%20data
666
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#%20K-Line%20Data
667
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
668
+ * @param {string} timeframe the length of time each candle represents
669
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
670
+ * @param {int} [limit] the maximum amount of candles to fetch
671
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
672
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
673
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
674
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
675
+ */
676
+ await this.loadMarkets();
677
+ let paginate = false;
678
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
679
+ if (paginate) {
680
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1440);
681
+ }
682
+ const market = this.market(symbol);
683
+ const request = {
684
+ 'symbol': market['id'],
685
+ };
686
+ request['interval'] = this.safeString(this.timeframes, timeframe, timeframe);
687
+ if (since !== undefined) {
688
+ request['startTime'] = since;
689
+ }
690
+ if (limit !== undefined) {
691
+ request['limit'] = limit;
692
+ }
693
+ const until = this.safeInteger2(params, 'until', 'endTime');
694
+ if (until !== undefined) {
695
+ params = this.omit(params, ['until']);
696
+ request['endTime'] = until;
697
+ }
698
+ let response = undefined;
699
+ if (market['spot']) {
700
+ response = await this.spotV1PublicGetMarketKline(this.extend(request, params));
701
+ }
702
+ else {
703
+ response = await this.swapV3PublicGetQuoteKlines(this.extend(request, params));
704
+ }
705
+ //
706
+ // {
707
+ // "code": 0,
708
+ // "msg": "",
709
+ // "data": [
710
+ // {
711
+ // "open": "19396.8",
712
+ // "close": "19394.4",
713
+ // "high": "19397.5",
714
+ // "low": "19385.7",
715
+ // "volume": "110.05",
716
+ // "time": 1666583700000
717
+ // },
718
+ // ...
719
+ // ]
720
+ // }
721
+ //
722
+ let ohlcvs = this.safeValue(response, 'data', []);
723
+ if (!Array.isArray(ohlcvs)) {
724
+ ohlcvs = [ohlcvs];
725
+ }
726
+ return this.parseOHLCVs(ohlcvs, market, timeframe, since, limit);
727
+ }
728
+ parseOHLCV(ohlcv, market = undefined) {
729
+ //
730
+ // {
731
+ // "open": "19394.4",
732
+ // "close": "19379.0",
733
+ // "high": "19394.4",
734
+ // "low": "19368.3",
735
+ // "volume": "167.44",
736
+ // "time": 1666584000000
737
+ // }
738
+ // spot
739
+ // [
740
+ // 1691402580000,
741
+ // 29093.61,
742
+ // 29093.93,
743
+ // 29087.73,
744
+ // 29093.24,
745
+ // 0.59,
746
+ // 1691402639999,
747
+ // 17221.07
748
+ // ]
749
+ //
750
+ if (Array.isArray(ohlcv)) {
751
+ return [
752
+ this.safeInteger(ohlcv, 0),
753
+ this.safeNumber(ohlcv, 1),
754
+ this.safeNumber(ohlcv, 2),
755
+ this.safeNumber(ohlcv, 3),
756
+ this.safeNumber(ohlcv, 4),
757
+ this.safeNumber(ohlcv, 5),
758
+ ];
759
+ }
760
+ return [
761
+ this.safeInteger(ohlcv, 'time'),
762
+ this.safeNumber(ohlcv, 'open'),
763
+ this.safeNumber(ohlcv, 'high'),
764
+ this.safeNumber(ohlcv, 'low'),
765
+ this.safeNumber(ohlcv, 'close'),
766
+ this.safeNumber(ohlcv, 'volume'),
767
+ ];
768
+ }
769
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
770
+ /**
771
+ * @method
772
+ * @name bingx#fetchTrades
773
+ * @description get the list of most recent trades for a particular symbol
774
+ * @see https://bingx-api.github.io/docs/#/spot/market-api.html#Query%20transaction%20records
775
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#The%20latest%20Trade%20of%20a%20Trading%20Pair
776
+ * @param {string} symbol unified symbol of the market to fetch trades for
777
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
778
+ * @param {int} [limit] the maximum amount of trades to fetch
779
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
780
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
781
+ */
782
+ await this.loadMarkets();
783
+ const market = this.market(symbol);
784
+ const request = {
785
+ 'symbol': market['id'],
786
+ };
787
+ if (limit !== undefined) {
788
+ request['limit'] = Math.min(limit, 100); // avoid API exception "limit should less than 100"
789
+ }
790
+ let response = undefined;
791
+ let marketType = undefined;
792
+ [marketType, params] = this.handleMarketTypeAndParams('fetchTrades', market, params);
793
+ if (marketType === 'spot') {
794
+ response = await this.spotV1PublicGetMarketTrades(this.extend(request, params));
795
+ }
796
+ else {
797
+ response = await this.swapV2PublicGetQuoteTrades(this.extend(request, params));
798
+ }
799
+ //
800
+ // spot
801
+ //
802
+ // {
803
+ // "code": 0,
804
+ // "data": [
805
+ // {
806
+ // "id": 43148253,
807
+ // "price": 25714.71,
808
+ // "qty": 1.674571,
809
+ // "time": 1655085975589,
810
+ // "buyerMaker": false
811
+ // }
812
+ // ]
813
+ // }
814
+ //
815
+ // swap
816
+ //
817
+ // {
818
+ // "code":0,
819
+ // "msg":"",
820
+ // "data":[
821
+ // {
822
+ // "time": 1672025549368,
823
+ // "isBuyerMaker": true,
824
+ // "price": "16885.0",
825
+ // "qty": "3.3002",
826
+ // "quoteQty": "55723.87"
827
+ // },
828
+ // ...
829
+ // ]
830
+ // }
831
+ //
832
+ const trades = this.safeValue(response, 'data', []);
833
+ return this.parseTrades(trades, market, since, limit);
834
+ }
835
+ parseTrade(trade, market = undefined) {
836
+ //
837
+ // spot
838
+ // fetchTrades
839
+ //
840
+ // {
841
+ // "id": 43148253,
842
+ // "price": 25714.71,
843
+ // "qty": 1.674571,
844
+ // "time": 1655085975589,
845
+ // "buyerMaker": false
846
+ // }
847
+ //
848
+ // swap
849
+ // fetchTrades
850
+ //
851
+ // {
852
+ // "time": 1672025549368,
853
+ // "isBuyerMaker": true,
854
+ // "price": "16885.0",
855
+ // "qty": "3.3002",
856
+ // "quoteQty": "55723.87"
857
+ // }
858
+ //
859
+ // swap
860
+ // fetchMyTrades
861
+ //
862
+ // {
863
+ // "volume": "0.1",
864
+ // "price": "106.75",
865
+ // "amount": "10.6750",
866
+ // "commission": "-0.0053",
867
+ // "currency": "USDT",
868
+ // "orderId": "1676213270274379776",
869
+ // "liquidatedPrice": "0.00",
870
+ // "liquidatedMarginRatio": "0.00",
871
+ // "filledTime": "2023-07-04T20:56:01.000+0800"
872
+ // }
873
+ //
874
+ //
875
+ // ws
876
+ //
877
+ // spot
878
+ //
879
+ // {
880
+ // "E": 1690214529432,
881
+ // "T": 1690214529386,
882
+ // "e": "trade",
883
+ // "m": true,
884
+ // "p": "29110.19",
885
+ // "q": "0.1868",
886
+ // "s": "BTC-USDT",
887
+ // "t": "57903921"
888
+ // }
889
+ //
890
+ // swap
891
+ //
892
+ // {
893
+ // "q": "0.0421",
894
+ // "p": "29023.5",
895
+ // "T": 1690221401344,
896
+ // "m": false,
897
+ // "s": "BTC-USDT"
898
+ // }
899
+ //
900
+ let time = this.safeIntegerN(trade, ['time', 'filledTm', 'T']);
901
+ const datetimeId = this.safeString(trade, 'filledTm');
902
+ if (datetimeId !== undefined) {
903
+ time = this.parse8601(datetimeId);
904
+ }
905
+ if (time === 0) {
906
+ time = undefined;
907
+ }
908
+ const cost = this.safeString(trade, 'quoteQty');
909
+ const type = (cost === undefined) ? 'spot' : 'swap';
910
+ const currencyId = this.safeString2(trade, 'currency', 'N');
911
+ const currencyCode = this.safeCurrencyCode(currencyId);
912
+ const m = this.safeValue(trade, 'm');
913
+ const marketId = this.safeString(trade, 's');
914
+ const isBuyerMaker = this.safeValue2(trade, 'buyerMaker', 'isBuyerMaker');
915
+ let takeOrMaker = undefined;
916
+ if ((isBuyerMaker !== undefined) || (m !== undefined)) {
917
+ takeOrMaker = (isBuyerMaker || m) ? 'maker' : 'taker';
918
+ }
919
+ let side = this.safeStringLower2(trade, 'side', 'S');
920
+ if (side === undefined) {
921
+ if ((isBuyerMaker !== undefined) || (m !== undefined)) {
922
+ side = (isBuyerMaker || m) ? 'sell' : 'buy';
923
+ takeOrMaker = 'taker';
924
+ }
925
+ }
926
+ return this.safeTrade({
927
+ 'id': this.safeStringN(trade, ['id', 't']),
928
+ 'info': trade,
929
+ 'timestamp': time,
930
+ 'datetime': this.iso8601(time),
931
+ 'symbol': this.safeSymbol(marketId, market, '-', type),
932
+ 'order': this.safeString2(trade, 'orderId', 'i'),
933
+ 'type': this.safeStringLower(trade, 'o'),
934
+ 'side': this.parseOrderSide(side),
935
+ 'takerOrMaker': takeOrMaker,
936
+ 'price': this.safeString2(trade, 'price', 'p'),
937
+ 'amount': this.safeStringN(trade, ['qty', 'volume', 'amount', 'q']),
938
+ 'cost': cost,
939
+ 'fee': {
940
+ 'cost': this.parseNumber(Precise["default"].stringAbs(this.safeString2(trade, 'commission', 'n'))),
941
+ 'currency': currencyCode,
942
+ 'rate': undefined,
943
+ },
944
+ }, market);
945
+ }
946
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
947
+ /**
948
+ * @method
949
+ * @name bingx#fetchOrderBook
950
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
951
+ * @see https://bingx-api.github.io/docs/#/spot/market-api.html#Query%20depth%20information
952
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Get%20Market%20Depth
953
+ * @param {string} symbol unified symbol of the market to fetch the order book for
954
+ * @param {int} [limit] the maximum amount of order book entries to return
955
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
956
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
957
+ */
958
+ await this.loadMarkets();
959
+ const market = this.market(symbol);
960
+ const request = {
961
+ 'symbol': market['id'],
962
+ };
963
+ if (limit !== undefined) {
964
+ request['limit'] = limit;
965
+ }
966
+ let response = undefined;
967
+ let marketType = undefined;
968
+ [marketType, params] = this.handleMarketTypeAndParams('fetchOrderBook', market, params);
969
+ if (marketType === 'spot') {
970
+ response = await this.spotV1PublicGetMarketDepth(this.extend(request, params));
971
+ }
972
+ else {
973
+ response = await this.swapV2PublicGetQuoteDepth(this.extend(request, params));
974
+ }
975
+ //
976
+ // spot
977
+ //
978
+ // {
979
+ // "code": 0,
980
+ // "data": {
981
+ // "bids": [
982
+ // [
983
+ // "26324.73",
984
+ // "0.37655"
985
+ // ],
986
+ // [
987
+ // "26324.71",
988
+ // "0.31888"
989
+ // ],
990
+ // ],
991
+ // "asks": [
992
+ // [
993
+ // "26340.30",
994
+ // "6.45221"
995
+ // ],
996
+ // [
997
+ // "26340.15",
998
+ // "6.73261"
999
+ // ],
1000
+ // ]}
1001
+ // }
1002
+ //
1003
+ // swap
1004
+ //
1005
+ // {
1006
+ // "code": 0,
1007
+ // "msg": "",
1008
+ // "data": {
1009
+ // "T": 1683914263304,
1010
+ // "bids": [
1011
+ // [
1012
+ // "26300.90000000",
1013
+ // "30408.00000000"
1014
+ // ],
1015
+ // [
1016
+ // "26300.80000000",
1017
+ // "50906.00000000"
1018
+ // ],
1019
+ // ],
1020
+ // "asks": [
1021
+ // [
1022
+ // "26301.00000000",
1023
+ // "43616.00000000"
1024
+ // ],
1025
+ // [
1026
+ // "26301.10000000",
1027
+ // "49402.00000000"
1028
+ // ],
1029
+ // ]}
1030
+ // }
1031
+ //
1032
+ const orderbook = this.safeValue(response, 'data', {});
1033
+ const timestamp = this.safeInteger2(orderbook, 'T', 'ts');
1034
+ return this.parseOrderBook(orderbook, market['symbol'], timestamp, 'bids', 'asks', 0, 1);
1035
+ }
1036
+ async fetchFundingRate(symbol, params = {}) {
1037
+ /**
1038
+ * @method
1039
+ * @name bingx#fetchFundingRate
1040
+ * @description fetch the current funding rate
1041
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Current%20Funding%20Rate
1042
+ * @param {string} symbol unified market symbol
1043
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1044
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
1045
+ */
1046
+ await this.loadMarkets();
1047
+ const market = this.market(symbol);
1048
+ const request = {
1049
+ 'symbol': market['id'],
1050
+ };
1051
+ const response = await this.swapV2PublicGetQuotePremiumIndex(this.extend(request, params));
1052
+ //
1053
+ // {
1054
+ // "code":0,
1055
+ // "msg":"",
1056
+ // "data":[
1057
+ // {
1058
+ // "symbol": "BTC-USDT",
1059
+ // "markPrice": "16884.5",
1060
+ // "indexPrice": "16886.9",
1061
+ // "lastFundingRate": "0.0001",
1062
+ // "nextFundingTime": 1672041600000
1063
+ // },
1064
+ // ...
1065
+ // ]
1066
+ // }
1067
+ //
1068
+ const data = this.safeValue(response, 'data', {});
1069
+ return this.parseFundingRate(data, market);
1070
+ }
1071
+ parseFundingRate(contract, market = undefined) {
1072
+ //
1073
+ // {
1074
+ // "symbol": "BTC-USDT",
1075
+ // "markPrice": "16884.5",
1076
+ // "indexPrice": "16886.9",
1077
+ // "lastFundingRate": "0.0001",
1078
+ // "nextFundingTime": 1672041600000
1079
+ // }
1080
+ //
1081
+ const marketId = this.safeString(contract, 'symbol');
1082
+ const nextFundingTimestamp = this.safeInteger(contract, 'nextFundingTime');
1083
+ return {
1084
+ 'info': contract,
1085
+ 'symbol': this.safeSymbol(marketId, market, '-', 'swap'),
1086
+ 'markPrice': this.safeNumber(contract, 'markPrice'),
1087
+ 'indexPrice': this.safeNumber(contract, 'indexPrice'),
1088
+ 'interestRate': undefined,
1089
+ 'estimatedSettlePrice': undefined,
1090
+ 'timestamp': undefined,
1091
+ 'datetime': undefined,
1092
+ 'fundingRate': this.safeNumber(contract, 'lastFundingRate'),
1093
+ 'fundingTimestamp': undefined,
1094
+ 'fundingDatetime': undefined,
1095
+ 'nextFundingRate': undefined,
1096
+ 'nextFundingTimestamp': nextFundingTimestamp,
1097
+ 'nextFundingDatetime': this.iso8601(nextFundingTimestamp),
1098
+ 'previousFundingRate': undefined,
1099
+ 'previousFundingTimestamp': undefined,
1100
+ 'previousFundingDatetime': undefined,
1101
+ };
1102
+ }
1103
+ async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1104
+ /**
1105
+ * @method
1106
+ * @name bingx#fetchFundingRateHistory
1107
+ * @description fetches historical funding rate prices
1108
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Funding%20Rate%20History
1109
+ * @param {string} symbol unified symbol of the market to fetch the funding rate history for
1110
+ * @param {int} [since] timestamp in ms of the earliest funding rate to fetch
1111
+ * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
1112
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1113
+ * @param {int} [params.until] timestamp in ms of the latest funding rate to fetch
1114
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1115
+ * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
1116
+ */
1117
+ if (symbol === undefined) {
1118
+ throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
1119
+ }
1120
+ await this.loadMarkets();
1121
+ let paginate = false;
1122
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
1123
+ if (paginate) {
1124
+ return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params);
1125
+ }
1126
+ const market = this.market(symbol);
1127
+ const request = {
1128
+ 'symbol': market['id'],
1129
+ };
1130
+ if (since !== undefined) {
1131
+ request['startTime'] = since;
1132
+ }
1133
+ if (limit !== undefined) {
1134
+ request['limit'] = limit;
1135
+ }
1136
+ const until = this.safeInteger2(params, 'until', 'startTime');
1137
+ if (until !== undefined) {
1138
+ params = this.omit(params, ['until']);
1139
+ request['startTime'] = until;
1140
+ }
1141
+ const response = await this.swapV2PublicGetQuoteFundingRate(this.extend(request, params));
1142
+ //
1143
+ // {
1144
+ // "code":0,
1145
+ // "msg":"",
1146
+ // "data":[
1147
+ // {
1148
+ // "symbol": "BTC-USDT",
1149
+ // "fundingRate": "0.0001",
1150
+ // "fundingTime": 1585684800000
1151
+ // },
1152
+ // ...
1153
+ // ]
1154
+ // }
1155
+ //
1156
+ const data = this.safeValue(response, 'data', []);
1157
+ const rates = [];
1158
+ for (let i = 0; i < data.length; i++) {
1159
+ const entry = data[i];
1160
+ const marketId = this.safeString(entry, 'symbol');
1161
+ const symbolInner = this.safeSymbol(marketId, market, '-', 'swap');
1162
+ const timestamp = this.safeInteger(entry, 'fundingTime');
1163
+ rates.push({
1164
+ 'info': entry,
1165
+ 'symbol': symbolInner,
1166
+ 'fundingRate': this.safeNumber(entry, 'fundingRate'),
1167
+ 'timestamp': timestamp,
1168
+ 'datetime': this.iso8601(timestamp),
1169
+ });
1170
+ }
1171
+ const sorted = this.sortBy(rates, 'timestamp');
1172
+ return this.filterBySymbolSinceLimit(sorted, market['symbol'], since, limit);
1173
+ }
1174
+ async fetchOpenInterest(symbol, params = {}) {
1175
+ /**
1176
+ * @method
1177
+ * @name bingx#fetchOpenInterest
1178
+ * @description Retrieves the open interest of a currency
1179
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Get%20Swap%20Open%20Positions
1180
+ * @param {string} symbol Unified CCXT market symbol
1181
+ * @param {object} [params] exchange specific parameters
1182
+ * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure}
1183
+ */
1184
+ await this.loadMarkets();
1185
+ const market = this.market(symbol);
1186
+ const request = {
1187
+ 'symbol': market['id'],
1188
+ };
1189
+ const response = await this.swapV2PublicGetQuoteOpenInterest(this.extend(request, params));
1190
+ //
1191
+ // {
1192
+ // "code": 0,
1193
+ // "msg": "",
1194
+ // "data": {
1195
+ // "openInterest": "3289641547.10",
1196
+ // "symbol": "BTC-USDT",
1197
+ // "time": 1672026617364
1198
+ // }
1199
+ // }
1200
+ //
1201
+ const data = this.safeValue(response, 'data', {});
1202
+ return this.parseOpenInterest(data, market);
1203
+ }
1204
+ parseOpenInterest(interest, market = undefined) {
1205
+ //
1206
+ // {
1207
+ // "openInterest": "3289641547.10",
1208
+ // "symbol": "BTC-USDT",
1209
+ // "time": 1672026617364
1210
+ // }
1211
+ //
1212
+ const timestamp = this.safeInteger(interest, 'time');
1213
+ const id = this.safeString(interest, 'symbol');
1214
+ const symbol = this.safeSymbol(id, market, '-', 'swap');
1215
+ const openInterest = this.safeNumber(interest, 'openInterest');
1216
+ return this.safeOpenInterest({
1217
+ 'symbol': symbol,
1218
+ 'baseVolume': undefined,
1219
+ 'quoteVolume': undefined,
1220
+ 'openInterestAmount': undefined,
1221
+ 'openInterestValue': openInterest,
1222
+ 'timestamp': timestamp,
1223
+ 'datetime': this.iso8601(timestamp),
1224
+ 'info': interest,
1225
+ }, market);
1226
+ }
1227
+ async fetchTicker(symbol, params = {}) {
1228
+ /**
1229
+ * @method
1230
+ * @name bingx#fetchTicker
1231
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1232
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Get%20Ticker
1233
+ * @see https://bingx-api.github.io/docs/#/spot/market-api.html#24%E5%B0%8F%E6%97%B6%E4%BB%B7%E6%A0%BC%E5%8F%98%E5%8A%A8%E6%83%85%E5%86%B5
1234
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1235
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1236
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1237
+ */
1238
+ await this.loadMarkets();
1239
+ const market = this.market(symbol);
1240
+ const request = {
1241
+ 'symbol': market['id'],
1242
+ };
1243
+ let response = undefined;
1244
+ if (market['spot']) {
1245
+ response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
1246
+ }
1247
+ else {
1248
+ response = await this.swapV2PublicGetQuoteTicker(this.extend(request, params));
1249
+ }
1250
+ const data = this.safeValue(response, 'data');
1251
+ const ticker = this.safeValue(data, 0, data);
1252
+ return this.parseTicker(ticker, market);
1253
+ }
1254
+ async fetchTickers(symbols = undefined, params = {}) {
1255
+ /**
1256
+ * @method
1257
+ * @name bingx#fetchTickers
1258
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1259
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Get%20Ticker
1260
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1261
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1262
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1263
+ */
1264
+ await this.loadMarkets();
1265
+ let market = undefined;
1266
+ if (symbols !== undefined) {
1267
+ symbols = this.marketSymbols(symbols);
1268
+ const firstSymbol = this.safeString(symbols, 0);
1269
+ market = this.market(firstSymbol);
1270
+ }
1271
+ let type = undefined;
1272
+ [type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
1273
+ let response = undefined;
1274
+ if (type === 'spot') {
1275
+ response = await this.spotV1PublicGetTicker24hr(params);
1276
+ }
1277
+ else {
1278
+ response = await this.swapV2PublicGetQuoteTicker(params);
1279
+ }
1280
+ const tickers = this.safeValue(response, 'data');
1281
+ return this.parseTickers(tickers, symbols);
1282
+ }
1283
+ parseTicker(ticker, market = undefined) {
1284
+ //
1285
+ // spot
1286
+ // {
1287
+ // "symbol": "BTC-USDT",
1288
+ // "openPrice": "26032.08",
1289
+ // "highPrice": "26178.86",
1290
+ // "lowPrice": "25968.18",
1291
+ // "lastPrice": "26113.60",
1292
+ // "volume": "1161.79",
1293
+ // "quoteVolume": "30288466.44",
1294
+ // "openTime": "1693081020762",
1295
+ // "closeTime": "1693167420762",
1296
+ // added 2023-11-10:
1297
+ // "bidPrice": 16726.0,
1298
+ // "bidQty": 0.05,
1299
+ // "askPrice": 16726.0,
1300
+ // "askQty": 0.05,
1301
+ // }
1302
+ // swap
1303
+ //
1304
+ // {
1305
+ // "symbol": "BTC-USDT",
1306
+ // "priceChange": "52.5",
1307
+ // "priceChangePercent": "0.31%", // they started to add the percent sign in value
1308
+ // "lastPrice": "16880.5",
1309
+ // "lastQty": "2.2238", // only present in swap!
1310
+ // "highPrice": "16897.5",
1311
+ // "lowPrice": "16726.0",
1312
+ // "volume": "245870.1692",
1313
+ // "quoteVolume": "4151395117.73",
1314
+ // "openPrice": "16832.0",
1315
+ // "openTime": 1672026667803,
1316
+ // "closeTime": 1672026648425,
1317
+ // added 2023-11-10:
1318
+ // "bidPrice": 16726.0,
1319
+ // "bidQty": 0.05,
1320
+ // "askPrice": 16726.0,
1321
+ // "askQty": 0.05,
1322
+ // }
1323
+ //
1324
+ const marketId = this.safeString(ticker, 'symbol');
1325
+ const lastQty = this.safeString(ticker, 'lastQty');
1326
+ // in spot markets, lastQty is not present
1327
+ // it's (bad, but) the only way we can check the tickers origin
1328
+ const type = (lastQty === undefined) ? 'spot' : 'swap';
1329
+ market = this.safeMarket(marketId, market, undefined, type);
1330
+ const symbol = market['symbol'];
1331
+ const open = this.safeString(ticker, 'openPrice');
1332
+ const high = this.safeString(ticker, 'highPrice');
1333
+ const low = this.safeString(ticker, 'lowPrice');
1334
+ const close = this.safeString(ticker, 'lastPrice');
1335
+ const quoteVolume = this.safeString(ticker, 'quoteVolume');
1336
+ const baseVolume = this.safeString(ticker, 'volume');
1337
+ let percentage = this.safeString(ticker, 'priceChangePercent');
1338
+ if (percentage !== undefined) {
1339
+ percentage = percentage.replace('%', '');
1340
+ }
1341
+ const change = this.safeString(ticker, 'priceChange');
1342
+ const ts = this.safeInteger(ticker, 'closeTime');
1343
+ const datetime = this.iso8601(ts);
1344
+ const bid = this.safeString(ticker, 'bidPrice');
1345
+ const bidVolume = this.safeString(ticker, 'bidQty');
1346
+ const ask = this.safeString(ticker, 'askPrice');
1347
+ const askVolume = this.safeString(ticker, 'askQty');
1348
+ return this.safeTicker({
1349
+ 'symbol': symbol,
1350
+ 'timestamp': ts,
1351
+ 'datetime': datetime,
1352
+ 'high': high,
1353
+ 'low': low,
1354
+ 'bid': bid,
1355
+ 'bidVolume': bidVolume,
1356
+ 'ask': ask,
1357
+ 'askVolume': askVolume,
1358
+ 'vwap': undefined,
1359
+ 'open': open,
1360
+ 'close': close,
1361
+ 'last': undefined,
1362
+ 'previousClose': undefined,
1363
+ 'change': change,
1364
+ 'percentage': percentage,
1365
+ 'average': undefined,
1366
+ 'baseVolume': baseVolume,
1367
+ 'quoteVolume': quoteVolume,
1368
+ 'info': ticker,
1369
+ }, market);
1370
+ }
1371
+ async fetchBalance(params = {}) {
1372
+ /**
1373
+ * @method
1374
+ * @name bingx#fetchBalance
1375
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1376
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Assets
1377
+ * @see https://bingx-api.github.io/docs/#/swapV2/account-api.html#Get%20Perpetual%20Swap%20Account%20Asset%20Information
1378
+ * @see https://bingx-api.github.io/docs/#/standard/contract-interface.html#Query%20standard%20contract%20balance
1379
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1380
+ * @param {boolean} [params.standard] whether to fetch standard contract balances
1381
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1382
+ */
1383
+ await this.loadMarkets();
1384
+ let response = undefined;
1385
+ let standard = undefined;
1386
+ [standard, params] = this.handleOptionAndParams(params, 'fetchBalance', 'standard', false);
1387
+ const [marketType, marketTypeQuery] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
1388
+ if (standard) {
1389
+ response = await this.contractV1PrivateGetBalance(marketTypeQuery);
1390
+ }
1391
+ else if (marketType === 'spot') {
1392
+ response = await this.spotV1PrivateGetAccountBalance(marketTypeQuery);
1393
+ }
1394
+ else {
1395
+ response = await this.swapV2PrivateGetUserBalance(marketTypeQuery);
1396
+ }
1397
+ //
1398
+ // spot
1399
+ //
1400
+ // {
1401
+ // "code": 0,
1402
+ // "msg": "",
1403
+ // "ttl": 1,
1404
+ // "data": {
1405
+ // "balances": [
1406
+ // {
1407
+ // "asset": "USDT",
1408
+ // "free": "16.73971130673954",
1409
+ // "locked": "0"
1410
+ // }
1411
+ // ]
1412
+ // }
1413
+ // }
1414
+ //
1415
+ // swap
1416
+ //
1417
+ // {
1418
+ // "code": 0,
1419
+ // "msg": "",
1420
+ // "data": {
1421
+ // "balance": {
1422
+ // "asset": "USDT",
1423
+ // "balance": "15.6128",
1424
+ // "equity": "15.6128",
1425
+ // "unrealizedProfit": "0.0000",
1426
+ // "realisedProfit": "0.0000",
1427
+ // "availableMargin": "15.6128",
1428
+ // "usedMargin": "0.0000",
1429
+ // "freezedMargin": "0.0000"
1430
+ // }
1431
+ // }
1432
+ // }
1433
+ // standard futures
1434
+ // {
1435
+ // "code":"0",
1436
+ // "timestamp":"1691148990942",
1437
+ // "data":[
1438
+ // {
1439
+ // "asset":"VST",
1440
+ // "balance":"100000.00000000000000000000",
1441
+ // "crossWalletBalance":"100000.00000000000000000000",
1442
+ // "crossUnPnl":"0",
1443
+ // "availableBalance":"100000.00000000000000000000",
1444
+ // "maxWithdrawAmount":"100000.00000000000000000000",
1445
+ // "marginAvailable":false,
1446
+ // "updateTime":"1691148990902"
1447
+ // },
1448
+ // {
1449
+ // "asset":"USDT",
1450
+ // "balance":"0",
1451
+ // "crossWalletBalance":"0",
1452
+ // "crossUnPnl":"0",
1453
+ // "availableBalance":"0",
1454
+ // "maxWithdrawAmount":"0",
1455
+ // "marginAvailable":false,
1456
+ // "updateTime":"1691148990902"
1457
+ // },
1458
+ // ]
1459
+ // }
1460
+ //
1461
+ return this.parseBalance(response);
1462
+ }
1463
+ parseBalance(response) {
1464
+ const data = this.safeValue(response, 'data');
1465
+ const balances = this.safeValue2(data, 'balance', 'balances', data);
1466
+ const result = { 'info': response };
1467
+ if (Array.isArray(balances)) {
1468
+ for (let i = 0; i < balances.length; i++) {
1469
+ const balance = balances[i];
1470
+ const currencyId = this.safeString(balance, 'asset');
1471
+ const code = this.safeCurrencyCode(currencyId);
1472
+ const account = this.account();
1473
+ account['free'] = this.safeString2(balance, 'free', 'availableBalance');
1474
+ account['used'] = this.safeString(balance, 'locked');
1475
+ account['total'] = this.safeString(balance, 'balance');
1476
+ result[code] = account;
1477
+ }
1478
+ }
1479
+ else {
1480
+ const currencyId = this.safeString(balances, 'asset');
1481
+ const code = this.safeCurrencyCode(currencyId);
1482
+ const account = this.account();
1483
+ account['free'] = this.safeString(balances, 'availableMargin');
1484
+ account['used'] = this.safeString(balances, 'usedMargin');
1485
+ result[code] = account;
1486
+ }
1487
+ return this.safeBalance(result);
1488
+ }
1489
+ async fetchPositions(symbols = undefined, params = {}) {
1490
+ /**
1491
+ * @method
1492
+ * @name bingx#fetchPositions
1493
+ * @description fetch all open positions
1494
+ * @see https://bingx-api.github.io/docs/#/swapV2/account-api.html#Perpetual%20Swap%20Positions
1495
+ * @see https://bingx-api.github.io/docs/#/standard/contract-interface.html#Query%20standard%20contract%20balance
1496
+ * @param {string[]|undefined} symbols list of unified market symbols
1497
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1498
+ * @param {boolean} [params.standard] whether to fetch standard contract positions
1499
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
1500
+ */
1501
+ await this.loadMarkets();
1502
+ symbols = this.marketSymbols(symbols);
1503
+ let standard = undefined;
1504
+ [standard, params] = this.handleOptionAndParams(params, 'fetchPositions', 'standard', false);
1505
+ let response = undefined;
1506
+ if (standard) {
1507
+ response = await this.contractV1PrivateGetAllPosition(params);
1508
+ }
1509
+ else {
1510
+ response = await this.swapV2PrivateGetUserPositions(params);
1511
+ }
1512
+ //
1513
+ // {
1514
+ // "code": 0,
1515
+ // "msg": "",
1516
+ // "data": [
1517
+ // {
1518
+ // "symbol": "BTC-USDT",
1519
+ // "positionId": "12345678",
1520
+ // "positionSide": "LONG",
1521
+ // "isolated": true,
1522
+ // "positionAmt": "123.33",
1523
+ // "availableAmt": "128.99",
1524
+ // "unrealizedProfit": "1.22",
1525
+ // "realisedProfit": "8.1",
1526
+ // "initialMargin": "123.33",
1527
+ // "avgPrice": "2.2",
1528
+ // "leverage": 10,
1529
+ // }
1530
+ // ]
1531
+ // }
1532
+ //
1533
+ const positions = this.safeValue(response, 'data', []);
1534
+ return this.parsePositions(positions, symbols);
1535
+ }
1536
+ parsePosition(position, market = undefined) {
1537
+ //
1538
+ // {
1539
+ // "symbol": "BTC-USDT",
1540
+ // "positionId": "12345678",
1541
+ // "positionSide": "LONG",
1542
+ // "isolated": true,
1543
+ // "positionAmt": "123.33",
1544
+ // "availableAmt": "128.99",
1545
+ // "unrealizedProfit": "1.22",
1546
+ // "realisedProfit": "8.1",
1547
+ // "initialMargin": "123.33",
1548
+ // "avgPrice": "2.2",
1549
+ // "leverage": 10,
1550
+ // }
1551
+ //
1552
+ // standard position
1553
+ //
1554
+ // {
1555
+ // "currentPrice": "82.91",
1556
+ // "symbol": "LTC/USDT",
1557
+ // "initialMargin": "5.00000000000000000000",
1558
+ // "unrealizedProfit": "-0.26464500",
1559
+ // "leverage": "20.000000000",
1560
+ // "isolated": true,
1561
+ // "entryPrice": "83.13",
1562
+ // "positionSide": "LONG",
1563
+ // "positionAmt": "1.20365912",
1564
+ // }
1565
+ //
1566
+ let marketId = this.safeString(position, 'symbol', '');
1567
+ marketId = marketId.replace('/', '-'); // standard return different format
1568
+ const isolated = this.safeValue(position, 'isolated');
1569
+ let marginMode = undefined;
1570
+ if (isolated !== undefined) {
1571
+ marginMode = isolated ? 'isolated' : 'cross';
1572
+ }
1573
+ return this.safePosition({
1574
+ 'info': position,
1575
+ 'id': this.safeString(position, 'positionId'),
1576
+ 'symbol': this.safeSymbol(marketId, market, '-', 'swap'),
1577
+ 'notional': this.safeNumber(position, 'positionAmt'),
1578
+ 'marginMode': marginMode,
1579
+ 'liquidationPrice': undefined,
1580
+ 'entryPrice': this.safeNumber2(position, 'avgPrice', 'entryPrice'),
1581
+ 'unrealizedPnl': this.safeNumber(position, 'unrealizedProfit'),
1582
+ 'realizedPnl': this.safeNumber(position, 'realisedProfit'),
1583
+ 'percentage': undefined,
1584
+ 'contracts': this.safeNumber(position, 'positionAmt'),
1585
+ 'contractSize': undefined,
1586
+ 'markPrice': undefined,
1587
+ 'lastPrice': undefined,
1588
+ 'side': this.safeStringLower(position, 'positionSide'),
1589
+ 'hedged': undefined,
1590
+ 'timestamp': undefined,
1591
+ 'datetime': undefined,
1592
+ 'lastUpdateTimestamp': undefined,
1593
+ 'maintenanceMargin': undefined,
1594
+ 'maintenanceMarginPercentage': undefined,
1595
+ 'collateral': this.safeNumber(position, 'positionAmt'),
1596
+ 'initialMargin': this.safeNumber(position, 'initialMargin'),
1597
+ 'initialMarginPercentage': undefined,
1598
+ 'leverage': this.safeNumber(position, 'leverage'),
1599
+ 'marginRatio': undefined,
1600
+ 'stopLossPrice': undefined,
1601
+ 'takeProfitPrice': undefined,
1602
+ });
1603
+ }
1604
+ async createMarketOrderWithCost(symbol, side, cost, params = {}) {
1605
+ /**
1606
+ * @method
1607
+ * @name bingx#createMarketOrderWithCost
1608
+ * @description create a market order by providing the symbol, side and cost
1609
+ * @param {string} symbol unified symbol of the market to create an order in
1610
+ * @param {string} side 'buy' or 'sell'
1611
+ * @param {float} cost how much you want to trade in units of the quote currency
1612
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1613
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1614
+ */
1615
+ params['quoteOrderQty'] = cost;
1616
+ return await this.createOrder(symbol, 'market', side, cost, undefined, params);
1617
+ }
1618
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1619
+ /**
1620
+ * @method
1621
+ * @name bingx#createMarketBuyOrderWithCost
1622
+ * @description create a market buy order by providing the symbol and cost
1623
+ * @param {string} symbol unified symbol of the market to create an order in
1624
+ * @param {float} cost how much you want to trade in units of the quote currency
1625
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1626
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1627
+ */
1628
+ params['quoteOrderQty'] = cost;
1629
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1630
+ }
1631
+ async createMarketSellOrderWithCost(symbol, cost, params = {}) {
1632
+ /**
1633
+ * @method
1634
+ * @name bingx#createMarketSellOrderWithCost
1635
+ * @description create a market sell order by providing the symbol and cost
1636
+ * @param {string} symbol unified symbol of the market to create an order in
1637
+ * @param {float} cost how much you want to trade in units of the quote currency
1638
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1639
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1640
+ */
1641
+ params['quoteOrderQty'] = cost;
1642
+ return await this.createOrder(symbol, 'market', 'sell', cost, undefined, params);
1643
+ }
1644
+ createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
1645
+ /**
1646
+ * @method
1647
+ * @ignore
1648
+ * @name bingx#createOrderRequest
1649
+ * @description helper function to build request
1650
+ * @param {string} symbol unified symbol of the market to create an order in
1651
+ * @param {string} type 'market' or 'limit'
1652
+ * @param {string} side 'buy' or 'sell'
1653
+ * @param {float} amount how much you want to trade in units of the base currency
1654
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1655
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1656
+ * @returns {object} request to be sent to the exchange
1657
+ */
1658
+ const market = this.market(symbol);
1659
+ let postOnly = undefined;
1660
+ let marketType = undefined;
1661
+ [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
1662
+ type = type.toUpperCase();
1663
+ const request = {
1664
+ 'symbol': market['id'],
1665
+ 'type': type,
1666
+ 'side': side.toUpperCase(),
1667
+ };
1668
+ const isMarketOrder = type === 'MARKET';
1669
+ const isSpot = marketType === 'spot';
1670
+ const exchangeClientOrderId = isSpot ? 'newClientOrderId' : 'clientOrderID';
1671
+ const clientOrderId = this.safeString2(params, exchangeClientOrderId, 'clientOrderId');
1672
+ if (clientOrderId !== undefined) {
1673
+ request[exchangeClientOrderId] = clientOrderId;
1674
+ }
1675
+ const timeInForce = this.safeStringUpper(params, 'timeInForce');
1676
+ if (timeInForce === 'IOC') {
1677
+ request['timeInForce'] = 'IOC';
1678
+ }
1679
+ if (isSpot) {
1680
+ [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'POC', params);
1681
+ if (postOnly || (timeInForce === 'POC')) {
1682
+ request['timeInForce'] = 'POC';
1683
+ }
1684
+ const cost = this.safeNumber2(params, 'cost', 'quoteOrderQty');
1685
+ params = this.omit(params, 'cost');
1686
+ if (cost !== undefined) {
1687
+ request['quoteOrderQty'] = this.parseToNumeric(this.costToPrecision(symbol, cost));
1688
+ }
1689
+ else {
1690
+ if (market['spot'] && isMarketOrder && (price !== undefined)) {
1691
+ // keep the legacy behavior, to avoid breaking the old spot-market-buying code
1692
+ const calculatedCost = Precise["default"].stringMul(this.numberToString(amount), this.numberToString(price));
1693
+ request['quoteOrderQty'] = this.parseToNumeric(calculatedCost);
1694
+ }
1695
+ else {
1696
+ request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
1697
+ }
1698
+ }
1699
+ if (!isMarketOrder) {
1700
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1701
+ }
1702
+ }
1703
+ else {
1704
+ [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'PostOnly', params);
1705
+ if (postOnly || (timeInForce === 'PostOnly')) {
1706
+ request['timeInForce'] = 'PostOnly';
1707
+ }
1708
+ else if (timeInForce === 'GTC') {
1709
+ request['timeInForce'] = 'GTC';
1710
+ }
1711
+ else if (timeInForce === 'FOK') {
1712
+ request['timeInForce'] = 'FOK';
1713
+ }
1714
+ const triggerPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
1715
+ const stopLossPrice = this.safeString(params, 'stopLossPrice');
1716
+ const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
1717
+ const trailingAmount = this.safeString(params, 'trailingAmount');
1718
+ const trailingPercent = this.safeString2(params, 'trailingPercent', 'priceRate');
1719
+ const isTriggerOrder = triggerPrice !== undefined;
1720
+ const isStopLossPriceOrder = stopLossPrice !== undefined;
1721
+ const isTakeProfitPriceOrder = takeProfitPrice !== undefined;
1722
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1723
+ const isTrailingPercentOrder = trailingPercent !== undefined;
1724
+ const isTrailing = isTrailingAmountOrder || isTrailingPercentOrder;
1725
+ const stopLoss = this.safeValue(params, 'stopLoss');
1726
+ const takeProfit = this.safeValue(params, 'takeProfit');
1727
+ const isStopLoss = stopLoss !== undefined;
1728
+ const isTakeProfit = takeProfit !== undefined;
1729
+ if (((type === 'LIMIT') || (type === 'TRIGGER_LIMIT') || (type === 'STOP') || (type === 'TAKE_PROFIT')) && !isTrailing) {
1730
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1731
+ }
1732
+ let reduceOnly = this.safeValue(params, 'reduceOnly', false);
1733
+ if (isTriggerOrder) {
1734
+ request['stopPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, triggerPrice));
1735
+ if (isMarketOrder || (type === 'TRIGGER_MARKET')) {
1736
+ request['type'] = 'TRIGGER_MARKET';
1737
+ }
1738
+ else if ((type === 'LIMIT') || (type === 'TRIGGER_LIMIT')) {
1739
+ request['type'] = 'TRIGGER_LIMIT';
1740
+ }
1741
+ }
1742
+ else if (isStopLossPriceOrder || isTakeProfitPriceOrder) {
1743
+ // This can be used to set the stop loss and take profit, but the position needs to be opened first
1744
+ reduceOnly = true;
1745
+ if (isStopLossPriceOrder) {
1746
+ request['stopPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, stopLossPrice));
1747
+ if (isMarketOrder || (type === 'STOP_MARKET')) {
1748
+ request['type'] = 'STOP_MARKET';
1749
+ }
1750
+ else if ((type === 'LIMIT') || (type === 'STOP')) {
1751
+ request['type'] = 'STOP';
1752
+ }
1753
+ }
1754
+ else if (isTakeProfitPriceOrder) {
1755
+ request['stopPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, takeProfitPrice));
1756
+ if (isMarketOrder || (type === 'TAKE_PROFIT_MARKET')) {
1757
+ request['type'] = 'TAKE_PROFIT_MARKET';
1758
+ }
1759
+ else if ((type === 'LIMIT') || (type === 'TAKE_PROFIT')) {
1760
+ request['type'] = 'TAKE_PROFIT';
1761
+ }
1762
+ }
1763
+ }
1764
+ else if (isTrailing) {
1765
+ request['type'] = 'TRAILING_STOP_MARKET';
1766
+ if (isTrailingAmountOrder) {
1767
+ request['price'] = this.parseToNumeric(trailingAmount);
1768
+ }
1769
+ else if (isTrailingPercentOrder) {
1770
+ const requestTrailingPercent = Precise["default"].stringDiv(trailingPercent, '100');
1771
+ request['priceRate'] = this.parseToNumeric(requestTrailingPercent);
1772
+ }
1773
+ }
1774
+ if (isStopLoss || isTakeProfit) {
1775
+ if (isStopLoss) {
1776
+ const slTriggerPrice = this.safeString2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss);
1777
+ const slWorkingType = this.safeString(stopLoss, 'workingType', 'MARK_PRICE');
1778
+ const slType = this.safeString(stopLoss, 'type', 'STOP_MARKET');
1779
+ const slRequest = {
1780
+ 'stopPrice': this.parseToNumeric(this.priceToPrecision(symbol, slTriggerPrice)),
1781
+ 'workingType': slWorkingType,
1782
+ 'type': slType,
1783
+ };
1784
+ const slPrice = this.safeString(stopLoss, 'price');
1785
+ if (slPrice !== undefined) {
1786
+ slRequest['price'] = this.parseToNumeric(this.priceToPrecision(symbol, slPrice));
1787
+ }
1788
+ const slQuantity = this.safeString(stopLoss, 'quantity', amount);
1789
+ slRequest['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, slQuantity));
1790
+ request['stopLoss'] = this.json(slRequest);
1791
+ }
1792
+ if (isTakeProfit) {
1793
+ const tkTriggerPrice = this.safeString2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit);
1794
+ const tkWorkingType = this.safeString(takeProfit, 'workingType', 'MARK_PRICE');
1795
+ const tpType = this.safeString(takeProfit, 'type', 'TAKE_PROFIT_MARKET');
1796
+ const tpRequest = {
1797
+ 'stopPrice': this.parseToNumeric(this.priceToPrecision(symbol, tkTriggerPrice)),
1798
+ 'workingType': tkWorkingType,
1799
+ 'type': tpType,
1800
+ };
1801
+ const slPrice = this.safeString(takeProfit, 'price');
1802
+ if (slPrice !== undefined) {
1803
+ tpRequest['price'] = this.parseToNumeric(this.priceToPrecision(symbol, slPrice));
1804
+ }
1805
+ const tkQuantity = this.safeString(takeProfit, 'quantity', amount);
1806
+ tpRequest['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, tkQuantity));
1807
+ request['takeProfit'] = this.json(tpRequest);
1808
+ }
1809
+ }
1810
+ let positionSide = undefined;
1811
+ if (reduceOnly) {
1812
+ positionSide = (side === 'buy') ? 'SHORT' : 'LONG';
1813
+ }
1814
+ else {
1815
+ positionSide = (side === 'buy') ? 'LONG' : 'SHORT';
1816
+ }
1817
+ request['positionSide'] = positionSide;
1818
+ request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
1819
+ params = this.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'takeProfit', 'stopLoss', 'clientOrderId']);
1820
+ }
1821
+ return this.extend(request, params);
1822
+ }
1823
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1824
+ /**
1825
+ * @method
1826
+ * @name bingx#createOrder
1827
+ * @description create a trade order
1828
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Trade%20order
1829
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Create%20an%20Order
1830
+ * @param {string} symbol unified symbol of the market to create an order in
1831
+ * @param {string} type 'market' or 'limit'
1832
+ * @param {string} side 'buy' or 'sell'
1833
+ * @param {float} amount how much you want to trade in units of the base currency
1834
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1835
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1836
+ * @param {string} [params.clientOrderId] a unique id for the order
1837
+ * @param {bool} [params.postOnly] true to place a post only order
1838
+ * @param {string} [params.timeInForce] spot supports 'PO' and 'IOC', swap supports 'PO', 'GTC', 'IOC' and 'FOK'
1839
+ * @param {bool} [params.reduceOnly] *swap only* true or false whether the order is reduce only
1840
+ * @param {float} [params.triggerPrice] *swap only* triggerPrice at which the attached take profit / stop loss order will be triggered
1841
+ * @param {float} [params.stopLossPrice] *swap only* stop loss trigger price
1842
+ * @param {float} [params.takeProfitPrice] *swap only* take profit trigger price
1843
+ * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount
1844
+ * @param {float} [params.trailingAmount] *swap only* the quote amount to trail away from the current market price
1845
+ * @param {float} [params.trailingPercent] *swap only* the percent to trail away from the current market price
1846
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
1847
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
1848
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
1849
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
1850
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1851
+ */
1852
+ await this.loadMarkets();
1853
+ const market = this.market(symbol);
1854
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
1855
+ let response = undefined;
1856
+ if (market['swap']) {
1857
+ response = await this.swapV2PrivatePostTradeOrder(request);
1858
+ }
1859
+ else {
1860
+ response = await this.spotV1PrivatePostTradeOrder(request);
1861
+ }
1862
+ //
1863
+ // spot
1864
+ //
1865
+ // {
1866
+ // "code": 0,
1867
+ // "msg": "",
1868
+ // "data": {
1869
+ // "symbol": "XRP-USDT",
1870
+ // "orderId": 1514090846268424192,
1871
+ // "transactTime": 1649822362855,
1872
+ // "price": "0.5",
1873
+ // "origQty": "10",
1874
+ // "executedQty": "0",
1875
+ // "cummulativeQuoteQty": "0",
1876
+ // "status": "PENDING",
1877
+ // "type": "LIMIT",
1878
+ // "side": "BUY"
1879
+ // }
1880
+ // }
1881
+ //
1882
+ // swap
1883
+ //
1884
+ // {
1885
+ // "code": 0,
1886
+ // "msg": "",
1887
+ // "data": {
1888
+ // "order": {
1889
+ // "symbol": "BTC-USDT",
1890
+ // "orderId": 1709036527545438208,
1891
+ // "side": "BUY",
1892
+ // "positionSide": "LONG",
1893
+ // "type": "TRIGGER_LIMIT",
1894
+ // "clientOrderID": "",
1895
+ // "workingType": ""
1896
+ // }
1897
+ // }
1898
+ // }
1899
+ //
1900
+ if (typeof response === 'string') {
1901
+ // broken api engine : order-ids are too long numbers (i.e. 1742930526912864656)
1902
+ // and JSON.parse can not handle them in JS, so we have to use .parseJson
1903
+ // however, when order has an attached SL/TP, their value types need extra parsing
1904
+ response = this.fixStringifiedJsonMembers(response);
1905
+ response = this.parseJson(response);
1906
+ }
1907
+ const data = this.safeValue(response, 'data', {});
1908
+ const order = this.safeValue(data, 'order', data);
1909
+ return this.parseOrder(order, market);
1910
+ }
1911
+ async createOrders(orders, params = {}) {
1912
+ /**
1913
+ * @method
1914
+ * @name bingx#createOrders
1915
+ * @description create a list of trade orders
1916
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Batch%20Placing%20Orders
1917
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Bulk%20order
1918
+ * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1919
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1920
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1921
+ */
1922
+ await this.loadMarkets();
1923
+ const ordersRequests = [];
1924
+ let symbol = undefined;
1925
+ for (let i = 0; i < orders.length; i++) {
1926
+ const rawOrder = orders[i];
1927
+ const marketId = this.safeString(rawOrder, 'symbol');
1928
+ if (symbol === undefined) {
1929
+ symbol = marketId;
1930
+ }
1931
+ else {
1932
+ if (symbol !== marketId) {
1933
+ throw new errors.BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
1934
+ }
1935
+ }
1936
+ const type = this.safeString(rawOrder, 'type');
1937
+ const side = this.safeString(rawOrder, 'side');
1938
+ const amount = this.safeNumber(rawOrder, 'amount');
1939
+ const price = this.safeNumber(rawOrder, 'price');
1940
+ const orderParams = this.safeValue(rawOrder, 'params', {});
1941
+ const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
1942
+ ordersRequests.push(orderRequest);
1943
+ }
1944
+ const market = this.market(symbol);
1945
+ const request = {};
1946
+ let response = undefined;
1947
+ if (market['swap']) {
1948
+ request['batchOrders'] = this.json(ordersRequests);
1949
+ response = await this.swapV2PrivatePostTradeBatchOrders(request);
1950
+ }
1951
+ else {
1952
+ request['data'] = this.json(ordersRequests);
1953
+ response = await this.spotV1PrivatePostTradeBatchOrders(request);
1954
+ }
1955
+ //
1956
+ // spot
1957
+ //
1958
+ // {
1959
+ // "code": 0,
1960
+ // "msg": "",
1961
+ // "debugMsg": "",
1962
+ // "data": {
1963
+ // "orders": [
1964
+ // {
1965
+ // "symbol": "BTC-USDT",
1966
+ // "orderId": 1720661389564968960,
1967
+ // "transactTime": 1699072618272,
1968
+ // "price": "25000",
1969
+ // "origQty": "0.0002",
1970
+ // "executedQty": "0",
1971
+ // "cummulativeQuoteQty": "0",
1972
+ // "status": "PENDING",
1973
+ // "type": "LIMIT",
1974
+ // "side": "BUY"
1975
+ // },
1976
+ // ]
1977
+ // }
1978
+ // }
1979
+ //
1980
+ // swap
1981
+ //
1982
+ // {
1983
+ // "code": 0,
1984
+ // "msg": "",
1985
+ // "data": {
1986
+ // "orders": [
1987
+ // {
1988
+ // "symbol": "BTC-USDT",
1989
+ // "orderId": 1720657081994006528,
1990
+ // "side": "BUY",
1991
+ // "positionSide": "LONG",
1992
+ // "type": "LIMIT",
1993
+ // "clientOrderID": "",
1994
+ // "workingType": ""
1995
+ // },
1996
+ // ]
1997
+ // }
1998
+ // }
1999
+ //
2000
+ const data = this.safeValue(response, 'data', {});
2001
+ const result = this.safeValue(data, 'orders', []);
2002
+ return this.parseOrders(result, market);
2003
+ }
2004
+ parseOrderSide(side) {
2005
+ const sides = {
2006
+ 'BUY': 'buy',
2007
+ 'SELL': 'sell',
2008
+ 'SHORT': 'sell',
2009
+ 'LONG': 'buy',
2010
+ };
2011
+ return this.safeString(sides, side, side);
2012
+ }
2013
+ parseOrder(order, market = undefined) {
2014
+ //
2015
+ // spot
2016
+ // createOrder, createOrders, cancelOrder
2017
+ //
2018
+ // {
2019
+ // "symbol": "XRP-USDT",
2020
+ // "orderId": 1514090846268424192,
2021
+ // "transactTime": 1649822362855,
2022
+ // "price": "0.5",
2023
+ // "origQty": "10",
2024
+ // "executedQty": "0",
2025
+ // "cummulativeQuoteQty": "0",
2026
+ // "status": "PENDING",
2027
+ // "type": "LIMIT",
2028
+ // "side": "BUY"
2029
+ // }
2030
+ //
2031
+ // fetchOrder
2032
+ //
2033
+ // {
2034
+ // "symbol": "ETH-USDT",
2035
+ // "orderId": "1660602123001266176",
2036
+ // "price": "1700",
2037
+ // "origQty": "0.003",
2038
+ // "executedQty": "0",
2039
+ // "cummulativeQuoteQty": "0",
2040
+ // "status": "PENDING",
2041
+ // "type": "LIMIT",
2042
+ // "side": "BUY",
2043
+ // "time": "1684753373276",
2044
+ // "updateTime": "1684753373276",
2045
+ // "origQuoteOrderQty": "0",
2046
+ // "fee": "0",
2047
+ // "feeAsset": "ETH"
2048
+ // }
2049
+ //
2050
+ // fetchOpenOrders, fetchClosedOrders
2051
+ //
2052
+ // {
2053
+ // "symbol": "XRP-USDT",
2054
+ // "orderId": 1514073325788200960,
2055
+ // "price": "0.5",
2056
+ // "StopPrice": "0",
2057
+ // "origQty": "20",
2058
+ // "executedQty": "10",
2059
+ // "cummulativeQuoteQty": "5",
2060
+ // "status": "PENDING",
2061
+ // "type": "LIMIT",
2062
+ // "side": "BUY",
2063
+ // "time": 1649818185647,
2064
+ // "updateTime": 1649818185647,
2065
+ // "origQuoteOrderQty": "0"
2066
+ // "fee": "-0.01"
2067
+ // }
2068
+ //
2069
+ //
2070
+ // swap
2071
+ // createOrder, createOrders
2072
+ //
2073
+ // {
2074
+ // "symbol": "BTC-USDT",
2075
+ // "orderId": 1590973236294713344,
2076
+ // "side": "BUY",
2077
+ // "positionSide": "LONG",
2078
+ // "type": "LIMIT"
2079
+ // }
2080
+ //
2081
+ // fetchOrder, fetchOpenOrders, fetchClosedOrders
2082
+ //
2083
+ // {
2084
+ // "symbol": "BTC-USDT",
2085
+ // "orderId": 1709036527545438208,
2086
+ // "side": "BUY",
2087
+ // "positionSide": "LONG",
2088
+ // "type": "TRIGGER_LIMIT",
2089
+ // "origQty": "0.0010",
2090
+ // "price": "22000.0",
2091
+ // "executedQty": "0.0000",
2092
+ // "avgPrice": "0.0",
2093
+ // "cumQuote": "",
2094
+ // "stopPrice": "23000.0",
2095
+ // "profit": "",
2096
+ // "commission": "",
2097
+ // "status": "NEW",
2098
+ // "time": 1696301035187,
2099
+ // "updateTime": 1696301035187,
2100
+ // "clientOrderId": "",
2101
+ // "leverage": "",
2102
+ // "takeProfit": "",
2103
+ // "stopLoss": "",
2104
+ // "advanceAttr": 0,
2105
+ // "positionID": 0,
2106
+ // "takeProfitEntrustPrice": 0,
2107
+ // "stopLossEntrustPrice": 0,
2108
+ // "orderType": "",
2109
+ // "workingType": "MARK_PRICE"
2110
+ // }
2111
+ // with tp and sl
2112
+ // {
2113
+ // orderId: 1741440894764281900,
2114
+ // symbol: 'LTC-USDT',
2115
+ // positionSide: 'LONG',
2116
+ // side: 'BUY',
2117
+ // type: 'MARKET',
2118
+ // price: 0,
2119
+ // quantity: 1,
2120
+ // stopPrice: 0,
2121
+ // workingType: 'MARK_PRICE',
2122
+ // clientOrderID: '',
2123
+ // timeInForce: 'GTC',
2124
+ // priceRate: 0,
2125
+ // stopLoss: '{"stopPrice":50,"workingType":"MARK_PRICE","type":"STOP_MARKET","quantity":1}',
2126
+ // takeProfit: '{"stopPrice":150,"workingType":"MARK_PRICE","type":"TAKE_PROFIT_MARKET","quantity":1}',
2127
+ // reduceOnly: false
2128
+ // }
2129
+ //
2130
+ const positionSide = this.safeString2(order, 'positionSide', 'ps');
2131
+ const marketType = (positionSide === undefined) ? 'spot' : 'swap';
2132
+ const marketId = this.safeString2(order, 'symbol', 's');
2133
+ if (market === undefined) {
2134
+ market = this.safeMarket(marketId, undefined, undefined, marketType);
2135
+ }
2136
+ const symbol = this.safeSymbol(marketId, market, '-', marketType);
2137
+ const orderId = this.safeString2(order, 'orderId', 'i');
2138
+ const side = this.safeStringLower2(order, 'side', 'S');
2139
+ const type = this.safeStringLower2(order, 'type', 'o');
2140
+ const timestamp = this.safeIntegerN(order, ['time', 'transactTime', 'E']);
2141
+ const lastTradeTimestamp = this.safeInteger2(order, 'updateTime', 'T');
2142
+ const price = this.safeString2(order, 'price', 'p');
2143
+ const average = this.safeString2(order, 'avgPrice', 'ap');
2144
+ const amount = this.safeString2(order, 'origQty', 'q');
2145
+ const filled = this.safeString2(order, 'executedQty', 'z');
2146
+ const statusId = this.safeString2(order, 'status', 'X');
2147
+ let feeCurrencyCode = this.safeString2(order, 'feeAsset', 'N');
2148
+ const feeCost = this.safeStringN(order, ['fee', 'commission', 'n']);
2149
+ if ((feeCurrencyCode === undefined)) {
2150
+ if (market['spot']) {
2151
+ if (side === 'buy') {
2152
+ feeCurrencyCode = market['base'];
2153
+ }
2154
+ else {
2155
+ feeCurrencyCode = market['quote'];
2156
+ }
2157
+ }
2158
+ else {
2159
+ feeCurrencyCode = market['quote'];
2160
+ }
2161
+ }
2162
+ const fee = {
2163
+ 'currency': feeCurrencyCode,
2164
+ 'cost': Precise["default"].stringAbs(feeCost),
2165
+ };
2166
+ const clientOrderId = this.safeStringN(order, ['clientOrderID', 'origClientOrderId', 'c']);
2167
+ let stopLoss = this.safeValue(order, 'stopLoss');
2168
+ let stopLossPrice = undefined;
2169
+ if (stopLoss !== undefined) {
2170
+ stopLossPrice = this.safeNumber(stopLoss, 'stopLoss');
2171
+ }
2172
+ if ((stopLoss !== undefined) && (typeof stopLoss !== 'number')) {
2173
+ // stopLoss: '{"stopPrice":50,"workingType":"MARK_PRICE","type":"STOP_MARKET","quantity":1}',
2174
+ if (typeof stopLoss === 'string') {
2175
+ stopLoss = this.parseJson(stopLoss);
2176
+ }
2177
+ stopLossPrice = this.safeNumber(stopLoss, 'stopPrice');
2178
+ }
2179
+ let takeProfit = this.safeValue(order, 'takeProfit');
2180
+ let takeProfitPrice = undefined;
2181
+ if (takeProfit !== undefined) {
2182
+ takeProfitPrice = this.safeNumber(takeProfit, 'takeProfit');
2183
+ }
2184
+ if ((takeProfit !== undefined) && (typeof takeProfit !== 'number')) {
2185
+ // takeProfit: '{"stopPrice":150,"workingType":"MARK_PRICE","type":"TAKE_PROFIT_MARKET","quantity":1}',
2186
+ if (typeof takeProfit === 'string') {
2187
+ takeProfit = this.parseJson(takeProfit);
2188
+ }
2189
+ takeProfitPrice = this.safeNumber(takeProfit, 'stopPrice');
2190
+ }
2191
+ return this.safeOrder({
2192
+ 'info': order,
2193
+ 'id': orderId,
2194
+ 'clientOrderId': clientOrderId,
2195
+ 'timestamp': timestamp,
2196
+ 'datetime': this.iso8601(timestamp),
2197
+ 'lastTradeTimestamp': lastTradeTimestamp,
2198
+ 'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
2199
+ 'symbol': symbol,
2200
+ 'type': type,
2201
+ 'timeInForce': undefined,
2202
+ 'postOnly': undefined,
2203
+ 'side': this.parseOrderSide(side),
2204
+ 'price': price,
2205
+ 'stopPrice': this.safeNumber(order, 'stopPrice'),
2206
+ 'triggerPrice': this.safeNumber(order, 'stopPrice'),
2207
+ 'stopLossPrice': stopLossPrice,
2208
+ 'takeProfitPrice': takeProfitPrice,
2209
+ 'average': average,
2210
+ 'cost': undefined,
2211
+ 'amount': amount,
2212
+ 'filled': filled,
2213
+ 'remaining': undefined,
2214
+ 'status': this.parseOrderStatus(statusId),
2215
+ 'fee': fee,
2216
+ 'trades': undefined,
2217
+ }, market);
2218
+ }
2219
+ parseOrderStatus(status) {
2220
+ const statuses = {
2221
+ 'NEW': 'open',
2222
+ 'PENDING': 'open',
2223
+ 'PARTIALLY_FILLED': 'open',
2224
+ 'FILLED': 'closed',
2225
+ 'CANCELED': 'canceled',
2226
+ 'CANCELLED': 'canceled',
2227
+ 'FAILED': 'failed',
2228
+ };
2229
+ return this.safeString(statuses, status, status);
2230
+ }
2231
+ async cancelOrder(id, symbol = undefined, params = {}) {
2232
+ /**
2233
+ * @method
2234
+ * @name bingx#cancelOrder
2235
+ * @description cancels an open order
2236
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Cancel%20an%20Order
2237
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Cancel%20an%20Order
2238
+ * @param {string} id order id
2239
+ * @param {string} symbol unified symbol of the market the order was made in
2240
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2241
+ * @param {string} [params.clientOrderId] a unique id for the order
2242
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2243
+ */
2244
+ if (symbol === undefined) {
2245
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
2246
+ }
2247
+ await this.loadMarkets();
2248
+ const market = this.market(symbol);
2249
+ const request = {
2250
+ 'symbol': market['id'],
2251
+ };
2252
+ const clientOrderId = this.safeString2(params, 'clientOrderId', 'clientOrderID');
2253
+ params = this.omit(params, ['clientOrderId']);
2254
+ if (clientOrderId !== undefined) {
2255
+ request['clientOrderID'] = clientOrderId;
2256
+ }
2257
+ else {
2258
+ request['orderId'] = id;
2259
+ }
2260
+ let response = undefined;
2261
+ const [marketType, query] = this.handleMarketTypeAndParams('cancelOrder', market, params);
2262
+ if (marketType === 'spot') {
2263
+ response = await this.spotV1PrivatePostTradeCancel(this.extend(request, query));
2264
+ }
2265
+ else {
2266
+ response = await this.swapV2PrivateDeleteTradeOrder(this.extend(request, query));
2267
+ }
2268
+ //
2269
+ // spot
2270
+ //
2271
+ // {
2272
+ // "code": 0,
2273
+ // "msg": "",
2274
+ // "data": {
2275
+ // "symbol": "XRP-USDT",
2276
+ // "orderId": 1514090846268424192,
2277
+ // "price": "0.5",
2278
+ // "origQty": "10",
2279
+ // "executedQty": "0",
2280
+ // "cummulativeQuoteQty": "0",
2281
+ // "status": "CANCELED",
2282
+ // "type": "LIMIT",
2283
+ // "side": "BUY"
2284
+ // }
2285
+ // }
2286
+ //
2287
+ // swap
2288
+ //
2289
+ // {
2290
+ // "code": 0,
2291
+ // "msg": "",
2292
+ // "data": {
2293
+ // "order": {
2294
+ // "symbol": "LINK-USDT",
2295
+ // "orderId": 1597783850786750464,
2296
+ // "side": "BUY",
2297
+ // "positionSide": "LONG",
2298
+ // "type": "TRIGGER_MARKET",
2299
+ // "origQty": "5.0",
2300
+ // "price": "5.0000",
2301
+ // "executedQty": "0.0",
2302
+ // "avgPrice": "0.0000",
2303
+ // "cumQuote": "0",
2304
+ // "stopPrice": "5.0000",
2305
+ // "profit": "",
2306
+ // "commission": "",
2307
+ // "status": "CANCELLED",
2308
+ // "time": 1669776330000,
2309
+ // "updateTime": 1669776330000
2310
+ // }
2311
+ // }
2312
+ // }
2313
+ //
2314
+ const data = this.safeValue(response, 'data');
2315
+ const first = this.safeValue(data, 'order', data);
2316
+ return this.parseOrder(first, market);
2317
+ }
2318
+ async cancelAllOrders(symbol = undefined, params = {}) {
2319
+ /**
2320
+ * @method
2321
+ * @name bingx#cancelAllOrders
2322
+ * @description cancel all open orders
2323
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20orders%20by%20symbol
2324
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Cancel%20All%20Orders
2325
+ * @param {string} [symbol] unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
2326
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2327
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2328
+ */
2329
+ if (symbol === undefined) {
2330
+ throw new errors.ArgumentsRequired(this.id + ' cancelAllOrders() requires a symbol argument');
2331
+ }
2332
+ await this.loadMarkets();
2333
+ const market = this.market(symbol);
2334
+ const request = {
2335
+ 'symbol': market['id'],
2336
+ };
2337
+ let response = undefined;
2338
+ if (market['spot']) {
2339
+ response = await this.spotV1PrivatePostTradeCancelOpenOrders(this.extend(request, params));
2340
+ //
2341
+ // {
2342
+ // "code": 0,
2343
+ // "msg": "",
2344
+ // "debugMsg": "",
2345
+ // "data": {
2346
+ // "orders": [{
2347
+ // "symbol": "ADA-USDT",
2348
+ // "orderId": 1740659971369992192,
2349
+ // "transactTime": 1703840651730,
2350
+ // "price": 5,
2351
+ // "stopPrice": 0,
2352
+ // "origQty": 10,
2353
+ // "executedQty": 0,
2354
+ // "cummulativeQuoteQty": 0,
2355
+ // "status": "CANCELED",
2356
+ // "type": "LIMIT",
2357
+ // "side": "SELL"
2358
+ // }]
2359
+ // }
2360
+ // }
2361
+ //
2362
+ }
2363
+ else if (market['swap']) {
2364
+ response = await this.swapV2PrivateDeleteTradeAllOpenOrders(this.extend(request, params));
2365
+ //
2366
+ // {
2367
+ // "code": 0,
2368
+ // "msg": "",
2369
+ // "data": {
2370
+ // "success": [
2371
+ // {
2372
+ // "symbol": "LINK-USDT",
2373
+ // "orderId": 1597783835095859200,
2374
+ // "side": "BUY",
2375
+ // "positionSide": "LONG",
2376
+ // "type": "TRIGGER_LIMIT",
2377
+ // "origQty": "5.0",
2378
+ // "price": "9.0000",
2379
+ // "executedQty": "0.0",
2380
+ // "avgPrice": "0.0000",
2381
+ // "cumQuote": "0",
2382
+ // "stopPrice": "9.5000",
2383
+ // "profit": "",
2384
+ // "commission": "",
2385
+ // "status": "NEW",
2386
+ // "time": 1669776326000,
2387
+ // "updateTime": 1669776326000
2388
+ // }
2389
+ // ],
2390
+ // "failed": null
2391
+ // }
2392
+ // }
2393
+ //
2394
+ }
2395
+ else {
2396
+ throw new errors.BadRequest(this.id + ' cancelAllOrders is only supported for spot and swap markets.');
2397
+ }
2398
+ return response;
2399
+ }
2400
+ async cancelOrders(ids, symbol = undefined, params = {}) {
2401
+ /**
2402
+ * @method
2403
+ * @name bingx#cancelOrders
2404
+ * @description cancel multiple orders
2405
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Cancel%20a%20Batch%20of%20Orders
2406
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Cancel%20a%20Batch%20of%20Orders
2407
+ * @param {string[]} ids order ids
2408
+ * @param {string} symbol unified market symbol, default is undefined
2409
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2410
+ * @param {string[]} [params.clientOrderIds] client order ids
2411
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2412
+ */
2413
+ if (symbol === undefined) {
2414
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
2415
+ }
2416
+ await this.loadMarkets();
2417
+ const market = this.market(symbol);
2418
+ const request = {
2419
+ 'symbol': market['id'],
2420
+ };
2421
+ const clientOrderIds = this.safeValue(params, 'clientOrderIds');
2422
+ params = this.omit(params, 'clientOrderIds');
2423
+ let idsToParse = ids;
2424
+ const areClientOrderIds = (clientOrderIds !== undefined);
2425
+ if (areClientOrderIds) {
2426
+ idsToParse = clientOrderIds;
2427
+ }
2428
+ const parsedIds = [];
2429
+ for (let i = 0; i < idsToParse.length; i++) {
2430
+ const id = idsToParse[i];
2431
+ const stringId = id.toString();
2432
+ parsedIds.push(stringId);
2433
+ }
2434
+ let response = undefined;
2435
+ if (market['spot']) {
2436
+ const spotReqKey = areClientOrderIds ? 'clientOrderIDs' : 'orderIds';
2437
+ request[spotReqKey] = parsedIds.join(',');
2438
+ response = await this.spotV1PrivatePostTradeCancelOrders(this.extend(request, params));
2439
+ }
2440
+ else {
2441
+ if (areClientOrderIds) {
2442
+ request['clientOrderIDList'] = this.json(parsedIds);
2443
+ }
2444
+ else {
2445
+ request['orderIdList'] = parsedIds;
2446
+ }
2447
+ response = await this.swapV2PrivateDeleteTradeBatchOrders(this.extend(request, params));
2448
+ }
2449
+ //
2450
+ // {
2451
+ // "code": 0,
2452
+ // "msg": "",
2453
+ // "data": {
2454
+ // "success": [
2455
+ // {
2456
+ // "symbol": "LINK-USDT",
2457
+ // "orderId": 1597783850786750464,
2458
+ // "side": "BUY",
2459
+ // "positionSide": "LONG",
2460
+ // "type": "TRIGGER_MARKET",
2461
+ // "origQty": "5.0",
2462
+ // "price": "5.5710",
2463
+ // "executedQty": "0.0",
2464
+ // "avgPrice": "0.0000",
2465
+ // "cumQuote": "0",
2466
+ // "stopPrice": "5.0000",
2467
+ // "profit": "0.0000",
2468
+ // "commission": "0.000000",
2469
+ // "status": "CANCELLED",
2470
+ // "time": 1669776330000,
2471
+ // "updateTime": 1672370837000
2472
+ // }
2473
+ // ],
2474
+ // "failed": null
2475
+ // }
2476
+ // }
2477
+ //
2478
+ return response;
2479
+ }
2480
+ async fetchOrder(id, symbol = undefined, params = {}) {
2481
+ /**
2482
+ * @method
2483
+ * @name bingx#fetchOrder
2484
+ * @description fetches information on an order made by the user
2485
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Orders
2486
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Query%20Order
2487
+ * @param {string} symbol unified symbol of the market the order was made in
2488
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2489
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2490
+ */
2491
+ if (symbol === undefined) {
2492
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrders() requires a symbol argument');
2493
+ }
2494
+ await this.loadMarkets();
2495
+ const market = this.market(symbol);
2496
+ const request = {
2497
+ 'symbol': market['id'],
2498
+ 'orderId': id,
2499
+ };
2500
+ let response = undefined;
2501
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchOrder', market, params);
2502
+ if (marketType === 'spot') {
2503
+ response = await this.spotV1PrivateGetTradeQuery(this.extend(request, query));
2504
+ }
2505
+ else {
2506
+ response = await this.swapV2PrivateGetTradeOrder(this.extend(request, query));
2507
+ }
2508
+ //
2509
+ // spot
2510
+ //
2511
+ // {
2512
+ // "code": 0,
2513
+ // "msg": "",
2514
+ // "data": {
2515
+ // "symbol": "XRP-USDT",
2516
+ // "orderId": 1514087361158316032,
2517
+ // "price": "0.5",
2518
+ // "origQty": "10",
2519
+ // "executedQty": "0",
2520
+ // "cummulativeQuoteQty": "0",
2521
+ // "status": "CANCELED",
2522
+ // "type": "LIMIT",
2523
+ // "side": "BUY",
2524
+ // "time": 1649821532000,
2525
+ // "updateTime": 1649821543000,
2526
+ // "origQuoteOrderQty": "0",
2527
+ // "fee": "0",
2528
+ // "feeAsset": "XRP"
2529
+ // }
2530
+ // }
2531
+ //
2532
+ // swap
2533
+ //
2534
+ // {
2535
+ // "code": 0,
2536
+ // "msg": "",
2537
+ // "data": {
2538
+ // "order": {
2539
+ // "symbol": "BTC-USDT",
2540
+ // "orderId": 1597597642269917184,
2541
+ // "side": "SELL",
2542
+ // "positionSide": "LONG",
2543
+ // "type": "TAKE_PROFIT_MARKET",
2544
+ // "origQty": "1.0000",
2545
+ // "price": "0.0",
2546
+ // "executedQty": "0.0000",
2547
+ // "avgPrice": "0.0",
2548
+ // "cumQuote": "",
2549
+ // "stopPrice": "16494.0",
2550
+ // "profit": "",
2551
+ // "commission": "",
2552
+ // "status": "FILLED",
2553
+ // "time": 1669731935000,
2554
+ // "updateTime": 1669752524000
2555
+ // }
2556
+ // }
2557
+ // }
2558
+ //
2559
+ const data = this.safeValue(response, 'data');
2560
+ const first = this.safeValue(data, 'order', data);
2561
+ return this.parseOrder(first, market);
2562
+ }
2563
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2564
+ /**
2565
+ * @method
2566
+ * @name bingx#fetchOpenOrders
2567
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Open%20Orders
2568
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Query%20all%20current%20pending%20orders
2569
+ * @description fetch all unfilled currently open orders
2570
+ * @param {string} symbol unified market symbol
2571
+ * @param {int} [since] the earliest time in ms to fetch open orders for
2572
+ * @param {int} [limit] the maximum number of open order structures to retrieve
2573
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2574
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2575
+ */
2576
+ await this.loadMarkets();
2577
+ let market = undefined;
2578
+ const request = {};
2579
+ if (symbol !== undefined) {
2580
+ market = this.market(symbol);
2581
+ request['symbol'] = market['id'];
2582
+ }
2583
+ let response = undefined;
2584
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2585
+ if (marketType === 'spot') {
2586
+ response = await this.spotV1PrivateGetTradeOpenOrders(this.extend(request, query));
2587
+ }
2588
+ else {
2589
+ response = await this.swapV2PrivateGetTradeOpenOrders(this.extend(request, query));
2590
+ }
2591
+ //
2592
+ // spot
2593
+ //
2594
+ // {
2595
+ // "code": 0,
2596
+ // "msg": "",
2597
+ // "data": {
2598
+ // "orders": [
2599
+ // {
2600
+ // "symbol": "XRP-USDT",
2601
+ // "orderId": 1514073325788200960,
2602
+ // "price": "0.5",
2603
+ // "origQty": "20",
2604
+ // "executedQty": "0",
2605
+ // "cummulativeQuoteQty": "0",
2606
+ // "status": "PENDING",
2607
+ // "type": "LIMIT",
2608
+ // "side": "BUY",
2609
+ // "time": 1649818185647,
2610
+ // "updateTime": 1649818185647,
2611
+ // "origQuoteOrderQty": "0"
2612
+ // }
2613
+ // ]
2614
+ // }
2615
+ // }
2616
+ //
2617
+ // swap
2618
+ //
2619
+ // {
2620
+ // "code": 0,
2621
+ // "msg": "",
2622
+ // "data": {
2623
+ // "orders": [
2624
+ // {
2625
+ // "symbol": "LINK-USDT",
2626
+ // "orderId": 1585839271162413056,
2627
+ // "side": "BUY",
2628
+ // "positionSide": "LONG",
2629
+ // "type": "TRIGGER_MARKET",
2630
+ // "origQty": "5.0",
2631
+ // "price": "9",
2632
+ // "executedQty": "0.0",
2633
+ // "avgPrice": "0",
2634
+ // "cumQuote": "0",
2635
+ // "stopPrice": "5",
2636
+ // "profit": "0.0000",
2637
+ // "commission": "0.000000",
2638
+ // "status": "CANCELLED",
2639
+ // "time": 1667631605000,
2640
+ // "updateTime": 1667631605000
2641
+ // },
2642
+ // ]
2643
+ // }
2644
+ // }
2645
+ //
2646
+ const data = this.safeValue(response, 'data', []);
2647
+ const orders = this.safeValue(data, 'orders', []);
2648
+ return this.parseOrders(orders, market, since, limit);
2649
+ }
2650
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2651
+ /**
2652
+ * @method
2653
+ * @name bingx#fetchClosedOrders
2654
+ * @description fetches information on multiple closed orders made by the user
2655
+ * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Order%20History
2656
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#User's%20Force%20Orders
2657
+ * @see https://bingx-api.github.io/docs/#/standard/contract-interface.html#Historical%20order
2658
+ * @param {string} [symbol] unified market symbol of the market orders were made in
2659
+ * @param {int} [since] the earliest time in ms to fetch orders for
2660
+ * @param {int} [limit] the maximum number of order structures to retrieve
2661
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2662
+ * @param {int} [params.until] the latest time in ms to fetch orders for
2663
+ * @param {boolean} [params.standard] whether to fetch standard contract orders
2664
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2665
+ */
2666
+ if (symbol === undefined) {
2667
+ throw new errors.ArgumentsRequired(this.id + ' fetchClosedOrders() requires a symbol argument');
2668
+ }
2669
+ await this.loadMarkets();
2670
+ const market = this.market(symbol);
2671
+ const request = {
2672
+ 'symbol': market['id'],
2673
+ };
2674
+ let response = undefined;
2675
+ let standard = undefined;
2676
+ [standard, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'standard', false);
2677
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchClosedOrders', market, params);
2678
+ if (standard) {
2679
+ response = await this.contractV1PrivateGetAllOrders(this.extend(request, query));
2680
+ }
2681
+ else if (marketType === 'spot') {
2682
+ response = await this.spotV1PrivateGetTradeHistoryOrders(this.extend(request, query));
2683
+ }
2684
+ else {
2685
+ response = await this.swapV2PrivateGetTradeAllOrders(this.extend(request, query));
2686
+ }
2687
+ //
2688
+ // spot
2689
+ //
2690
+ // {
2691
+ // "code": 0,
2692
+ // "msg": "",
2693
+ // "data": {
2694
+ // "orders": [
2695
+ // {
2696
+ // "symbol": "XRP-USDT",
2697
+ // "orderId": 1514073325788200960,
2698
+ // "price": "0.5",
2699
+ // "origQty": "20",
2700
+ // "executedQty": "0",
2701
+ // "cummulativeQuoteQty": "0",
2702
+ // "status": "PENDING",
2703
+ // "type": "LIMIT",
2704
+ // "side": "BUY",
2705
+ // "time": 1649818185647,
2706
+ // "updateTime": 1649818185647,
2707
+ // "origQuoteOrderQty": "0"
2708
+ // }
2709
+ // ]
2710
+ // }
2711
+ // }
2712
+ //
2713
+ // swap
2714
+ //
2715
+ // {
2716
+ // "code": 0,
2717
+ // "msg": "",
2718
+ // "data": {
2719
+ // "orders": [
2720
+ // {
2721
+ // "symbol": "LINK-USDT",
2722
+ // "orderId": 1585839271162413056,
2723
+ // "side": "BUY",
2724
+ // "positionSide": "LONG",
2725
+ // "type": "TRIGGER_MARKET",
2726
+ // "origQty": "5.0",
2727
+ // "price": "9",
2728
+ // "executedQty": "0.0",
2729
+ // "avgPrice": "0",
2730
+ // "cumQuote": "0",
2731
+ // "stopPrice": "5",
2732
+ // "profit": "0.0000",
2733
+ // "commission": "0.000000",
2734
+ // "status": "CANCELLED",
2735
+ // "time": 1667631605000,
2736
+ // "updateTime": 1667631605000
2737
+ // },
2738
+ // ]
2739
+ // }
2740
+ // }
2741
+ //
2742
+ const data = this.safeValue(response, 'data', []);
2743
+ const orders = this.safeValue(data, 'orders', []);
2744
+ return this.parseOrders(orders, market, since, limit);
2745
+ }
2746
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
2747
+ /**
2748
+ * @method
2749
+ * @name bingx#transfer
2750
+ * @description transfer currency internally between wallets on the same account
2751
+ * @see https://bingx-api.github.io/docs/#/spot/account-api.html#User%20Universal%20Transfer
2752
+ * @param {string} code unified currency code
2753
+ * @param {float} amount amount to transfer
2754
+ * @param {string} fromAccount account to transfer from
2755
+ * @param {string} toAccount account to transfer to
2756
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2757
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2758
+ */
2759
+ await this.loadMarkets();
2760
+ const currency = this.currency(code);
2761
+ const accountsByType = this.safeValue(this.options, 'accountsByType', {});
2762
+ const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
2763
+ const toId = this.safeString(accountsByType, toAccount, toAccount);
2764
+ const request = {
2765
+ 'asset': currency['id'],
2766
+ 'amount': this.currencyToPrecision(code, amount),
2767
+ 'type': fromId + '_' + toId,
2768
+ };
2769
+ const response = await this.spotV3PrivateGetGetAssetTransfer(this.extend(request, params));
2770
+ //
2771
+ // {
2772
+ // "tranId":13526853623
2773
+ // }
2774
+ //
2775
+ return {
2776
+ 'info': response,
2777
+ 'id': this.safeString(response, 'tranId'),
2778
+ 'timestamp': undefined,
2779
+ 'datetime': undefined,
2780
+ 'currency': code,
2781
+ 'amount': amount,
2782
+ 'fromAccount': fromAccount,
2783
+ 'toAccount': toAccount,
2784
+ 'status': undefined,
2785
+ };
2786
+ }
2787
+ async fetchTransfers(code = undefined, since = undefined, limit = undefined, params = {}) {
2788
+ /**
2789
+ * @method
2790
+ * @name bingx#fetchTransfers
2791
+ * @description fetch a history of internal transfers made on an account
2792
+ * @see https://bingx-api.github.io/docs/#/spot/account-api.html#Query%20User%20Universal%20Transfer%20History%20(USER_DATA)
2793
+ * @param {string} [code] unified currency code of the currency transferred
2794
+ * @param {int} [since] the earliest time in ms to fetch transfers for
2795
+ * @param {int} [limit] the maximum number of transfers structures to retrieve
2796
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2797
+ * @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2798
+ */
2799
+ await this.loadMarkets();
2800
+ let currency = undefined;
2801
+ if (code !== undefined) {
2802
+ currency = this.currency(code);
2803
+ }
2804
+ const accountsByType = this.safeValue(this.options, 'accountsByType', {});
2805
+ const fromAccount = this.safeString(params, 'fromAccount');
2806
+ const toAccount = this.safeString(params, 'toAccount');
2807
+ const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
2808
+ const toId = this.safeString(accountsByType, toAccount, toAccount);
2809
+ if (fromId === undefined || toId === undefined) {
2810
+ throw new errors.ExchangeError(this.id + ' fromAccount & toAccount parameter are required');
2811
+ }
2812
+ const request = {
2813
+ 'type': fromId + '_' + toId,
2814
+ };
2815
+ if (since !== undefined) {
2816
+ request['startTime'] = since;
2817
+ }
2818
+ if (limit !== undefined) {
2819
+ request['size'] = limit;
2820
+ }
2821
+ const response = await this.spotV3PrivateGetAssetTransfer(this.extend(request, params));
2822
+ //
2823
+ // {
2824
+ // "total": 3,
2825
+ // "rows": [
2826
+ // {
2827
+ // "asset":"USDT",
2828
+ // "amount":"-100.00000000000000000000",
2829
+ // "type":"FUND_SFUTURES",
2830
+ // "status":"CONFIRMED",
2831
+ // "tranId":1067594500957016069,
2832
+ // "timestamp":1658388859000
2833
+ // },
2834
+ // ]
2835
+ // }
2836
+ //
2837
+ const rows = this.safeValue(response, 'rows', []);
2838
+ return this.parseTransfers(rows, currency, since, limit);
2839
+ }
2840
+ parseTransfer(transfer, currency = undefined) {
2841
+ const tranId = this.safeString(transfer, 'tranId');
2842
+ const timestamp = this.safeInteger(transfer, 'timestamp');
2843
+ const currencyCode = this.safeCurrencyCode(undefined, currency);
2844
+ const status = this.safeString(transfer, 'status');
2845
+ const accountsById = this.safeValue(this.options, 'accountsById', {});
2846
+ const typeId = this.safeString(transfer, 'type');
2847
+ const typeIdSplit = typeId.split('_');
2848
+ const fromId = this.safeString(typeIdSplit, 0);
2849
+ const toId = this.safeString(typeId, 1);
2850
+ const fromAccount = this.safeString(accountsById, fromId, fromId);
2851
+ const toAccount = this.safeString(accountsById, toId, toId);
2852
+ return {
2853
+ 'info': transfer,
2854
+ 'id': tranId,
2855
+ 'timestamp': timestamp,
2856
+ 'datetime': this.iso8601(timestamp),
2857
+ 'currency': currencyCode,
2858
+ 'amount': this.safeNumber(transfer, 'amount'),
2859
+ 'fromAccount': fromAccount,
2860
+ 'toAccount': toAccount,
2861
+ 'status': status,
2862
+ };
2863
+ }
2864
+ async fetchDepositAddress(code, params = {}) {
2865
+ /**
2866
+ * @method
2867
+ * @name bingx#fetchDepositAddress
2868
+ * @description fetch the deposit address for a currency associated with this account
2869
+ * @see https://bingx-api.github.io/docs/#/common/sub-account#Query%20Main%20Account%20Deposit%20Address
2870
+ * @param {string} code unified currency code
2871
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2872
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
2873
+ */
2874
+ await this.loadMarkets();
2875
+ const currency = this.currency(code);
2876
+ const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
2877
+ const recvWindow = this.safeInteger(this.parseParams, 'recvWindow', defaultRecvWindow);
2878
+ const request = {
2879
+ 'coin': currency['id'],
2880
+ 'offset': 0,
2881
+ 'limit': 1000,
2882
+ 'recvWindow': recvWindow,
2883
+ };
2884
+ const response = await this.walletsV1PrivateGetCapitalDepositAddress(this.extend(request, params));
2885
+ //
2886
+ // {
2887
+ // "code": "0",
2888
+ // "timestamp": "1695200226859",
2889
+ // "data": {
2890
+ // "data": [
2891
+ // {
2892
+ // "coinId": "799",
2893
+ // "coin": "USDT",
2894
+ // "network": "BEP20",
2895
+ // "address": "6a7eda2817462dabb6493277a2cfe0f5c3f2550b",
2896
+ // "tag": ''
2897
+ // }
2898
+ // ],
2899
+ // "total": "1"
2900
+ // }
2901
+ // }
2902
+ //
2903
+ const data = this.safeValue(this.safeValue(response, 'data'), 'data');
2904
+ const parsed = this.parseDepositAddresses(data, [currency['code']], false);
2905
+ return this.indexBy(parsed, 'network');
2906
+ }
2907
+ parseDepositAddress(depositAddress, currency = undefined) {
2908
+ //
2909
+ // {
2910
+ // "coinId": "799",
2911
+ // "coin": "USDT",
2912
+ // "network": "BEP20",
2913
+ // "address": "6a7eda2817462dabb6493277a2cfe0f5c3f2550b",
2914
+ // "tag": ''
2915
+ // }
2916
+ //
2917
+ const address = this.safeString(depositAddress, 'address');
2918
+ const tag = this.safeString(depositAddress, 'tag');
2919
+ const currencyId = this.safeString(depositAddress, 'coin');
2920
+ currency = this.safeCurrency(currencyId, currency);
2921
+ const code = currency['code'];
2922
+ const network = this.safeString(depositAddress, 'network');
2923
+ this.checkAddress(address);
2924
+ return {
2925
+ 'currency': code,
2926
+ 'address': address,
2927
+ 'tag': tag,
2928
+ 'network': network,
2929
+ 'info': depositAddress,
2930
+ };
2931
+ }
2932
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
2933
+ /**
2934
+ * @method
2935
+ * @name bingx#fetchDeposits
2936
+ * @description fetch all deposits made to an account
2937
+ * @see https://bingx-api.github.io/docs/#/spot/account-api.html#Deposit%20History(supporting%20network)
2938
+ * @param {string} [code] unified currency code
2939
+ * @param {int} [since] the earliest time in ms to fetch deposits for
2940
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
2941
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2942
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2943
+ */
2944
+ await this.loadMarkets();
2945
+ const request = {};
2946
+ let currency = undefined;
2947
+ if (code !== undefined) {
2948
+ currency = this.currency(code);
2949
+ request['coin'] = currency['id'];
2950
+ }
2951
+ if (since !== undefined) {
2952
+ request['startTime'] = since;
2953
+ }
2954
+ if (limit !== undefined) {
2955
+ request['limit'] = limit; // default 1000
2956
+ }
2957
+ const response = await this.spotV3PrivateGetCapitalDepositHisrec(this.extend(request, params));
2958
+ //
2959
+ // [
2960
+ // {
2961
+ // "amount":"0.00999800",
2962
+ // "coin":"PAXG",
2963
+ // "network":"ETH",
2964
+ // "status":1,
2965
+ // "address":"0x788cabe9236ce061e5a892e1a59395a81fc8d62c",
2966
+ // "addressTag":"",
2967
+ // "txId":"0xaad4654a3234aa6118af9b4b335f5ae81c360b2394721c019b5d1e75328b09f3",
2968
+ // "insertTime":1599621997000,
2969
+ // "transferType":0,
2970
+ // "unlockConfirm":"12/12", // confirm times for unlocking
2971
+ // "confirmTimes":"12/12"
2972
+ // },
2973
+ // ]
2974
+ //
2975
+ return this.parseTransactions(response, currency, since, limit);
2976
+ }
2977
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2978
+ /**
2979
+ * @method
2980
+ * @name bingx#fetchWithdrawals
2981
+ * @description fetch all withdrawals made from an account
2982
+ * @see https://bingx-api.github.io/docs/#/spot/account-api.html#Withdraw%20History%20(supporting%20network)
2983
+ * @param {string} [code] unified currency code
2984
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
2985
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
2986
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2987
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2988
+ */
2989
+ await this.loadMarkets();
2990
+ const request = {};
2991
+ let currency = undefined;
2992
+ if (code !== undefined) {
2993
+ currency = this.currency(code);
2994
+ request['coin'] = currency['id'];
2995
+ }
2996
+ if (since !== undefined) {
2997
+ request['startTime'] = since;
2998
+ }
2999
+ if (limit !== undefined) {
3000
+ request['limit'] = limit; // default 1000
3001
+ }
3002
+ const response = await this.spotV3PrivateGetCapitalWithdrawHistory(this.extend(request, params));
3003
+ //
3004
+ // [
3005
+ // {
3006
+ // "address": "0x94df8b352de7f46f64b01d3666bf6e936e44ce60",
3007
+ // "amount": "8.91000000",
3008
+ // "applyTime": "2019-10-12 11:12:02",
3009
+ // "coin": "USDT",
3010
+ // "id": "b6ae22b3aa844210a7041aee7589627c",
3011
+ // "withdrawOrderId": "WITHDRAWtest123",
3012
+ // "network": "ETH",
3013
+ // "transferType": 0
3014
+ // "status": 6,
3015
+ // "transactionFee": "0.004",
3016
+ // "confirmNo":3,
3017
+ // "info": "The address is not valid. Please confirm with the recipient",
3018
+ // "txId": "0xb5ef8c13b968a406cc62a93a8bd80f9e9a906ef1b3fcf20a2e48573c17659268"
3019
+ // },
3020
+ // ]
3021
+ //
3022
+ return this.parseTransactions(response, currency, since, limit);
3023
+ }
3024
+ parseTransaction(transaction, currency = undefined) {
3025
+ //
3026
+ // fetchDeposits
3027
+ //
3028
+ // {
3029
+ // "amount":"0.00999800",
3030
+ // "coin":"PAXG",
3031
+ // "network":"ETH",
3032
+ // "status":1,
3033
+ // "address":"0x788cabe9236ce061e5a892e1a59395a81fc8d62c",
3034
+ // "addressTag":"",
3035
+ // "txId":"0xaad4654a3234aa6118af9b4b335f5ae81c360b2394721c019b5d1e75328b09f3",
3036
+ // "insertTime":1599621997000,
3037
+ // "transferType":0,
3038
+ // "unlockConfirm":"12/12", // confirm times for unlocking
3039
+ // "confirmTimes":"12/12"
3040
+ // }
3041
+ //
3042
+ // fetchWithdrawals
3043
+ //
3044
+ // {
3045
+ // "address": "0x94df8b352de7f46f64b01d3666bf6e936e44ce60",
3046
+ // "amount": "8.91000000",
3047
+ // "applyTime": "2019-10-12 11:12:02",
3048
+ // "coin": "USDT",
3049
+ // "id": "b6ae22b3aa844210a7041aee7589627c",
3050
+ // "withdrawOrderId": "WITHDRAWtest123",
3051
+ // "network": "ETH",
3052
+ // "transferType": 0
3053
+ // "status": 6,
3054
+ // "transactionFee": "0.004",
3055
+ // "confirmNo":3,
3056
+ // "info": "The address is not valid. Please confirm with the recipient",
3057
+ // "txId": "0xb5ef8c13b968a406cc62a93a8bd80f9e9a906ef1b3fcf20a2e48573c17659268"
3058
+ // }
3059
+ //
3060
+ const address = this.safeString(transaction, 'address');
3061
+ const tag = this.safeString(transaction, 'addressTag');
3062
+ let timestamp = this.safeInteger(transaction, 'insertTime');
3063
+ let datetime = this.iso8601(timestamp);
3064
+ if (timestamp === undefined) {
3065
+ datetime = this.safeString(transaction, 'applyTime');
3066
+ timestamp = this.parse8601(datetime);
3067
+ }
3068
+ const network = this.safeString(transaction, 'network');
3069
+ const currencyId = this.safeString(transaction, 'coin');
3070
+ let code = this.safeCurrencyCode(currencyId, currency);
3071
+ if ((code !== undefined) && (code !== network) && code.indexOf(network) >= 0) {
3072
+ if (network !== undefined) {
3073
+ code = code.replace(network, '');
3074
+ }
3075
+ }
3076
+ const rawType = this.safeString(transaction, 'transferType');
3077
+ const type = (rawType === '0') ? 'deposit' : 'withdrawal';
3078
+ return {
3079
+ 'info': transaction,
3080
+ 'id': this.safeString(transaction, 'id'),
3081
+ 'txid': this.safeString(transaction, 'txId'),
3082
+ 'type': type,
3083
+ 'currency': code,
3084
+ 'network': this.networkIdToCode(network),
3085
+ 'amount': this.safeNumber(transaction, 'amount'),
3086
+ 'status': this.parseTransactionStatus(this.safeString(transaction, 'status')),
3087
+ 'timestamp': timestamp,
3088
+ 'datetime': datetime,
3089
+ 'address': address,
3090
+ 'addressFrom': undefined,
3091
+ 'addressTo': address,
3092
+ 'tag': tag,
3093
+ 'tagFrom': tag,
3094
+ 'tagTo': undefined,
3095
+ 'updated': undefined,
3096
+ 'comment': this.safeString(transaction, 'info'),
3097
+ 'fee': {
3098
+ 'currency': code,
3099
+ 'cost': this.safeNumber(transaction, 'transactionFee'),
3100
+ 'rate': undefined,
3101
+ },
3102
+ 'internal': undefined,
3103
+ };
3104
+ }
3105
+ parseTransactionStatus(status) {
3106
+ const statuses = {
3107
+ '0': 'pending',
3108
+ '1': 'ok',
3109
+ '10': 'pending',
3110
+ '20': 'rejected',
3111
+ '30': 'ok',
3112
+ '40': 'rejected',
3113
+ '50': 'ok',
3114
+ '60': 'pending',
3115
+ '70': 'rejected',
3116
+ '2': 'pending',
3117
+ '3': 'rejected',
3118
+ '4': 'pending',
3119
+ '5': 'rejected',
3120
+ '6': 'ok',
3121
+ };
3122
+ return this.safeString(statuses, status, status);
3123
+ }
3124
+ async setMarginMode(marginMode, symbol = undefined, params = {}) {
3125
+ /**
3126
+ * @method
3127
+ * @name bingx#setMarginMode
3128
+ * @description set margin mode to 'cross' or 'isolated'
3129
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Switch%20Margin%20Mode
3130
+ * @param {string} marginMode 'cross' or 'isolated'
3131
+ * @param {string} symbol unified market symbol
3132
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3133
+ * @returns {object} response from the exchange
3134
+ */
3135
+ if (symbol === undefined) {
3136
+ throw new errors.ArgumentsRequired(this.id + ' setMarginMode() requires a symbol argument');
3137
+ }
3138
+ await this.loadMarkets();
3139
+ const market = this.market(symbol);
3140
+ if (market['type'] !== 'swap') {
3141
+ throw new errors.BadSymbol(this.id + ' setMarginMode() supports swap contracts only');
3142
+ }
3143
+ marginMode = marginMode.toUpperCase();
3144
+ if (marginMode === 'CROSS') {
3145
+ marginMode = 'CROSSED';
3146
+ }
3147
+ if (marginMode !== 'ISOLATED' && marginMode !== 'CROSSED') {
3148
+ throw new errors.BadRequest(this.id + ' setMarginMode() marginMode argument should be isolated or cross');
3149
+ }
3150
+ const request = {
3151
+ 'symbol': market['id'],
3152
+ 'marginType': marginMode,
3153
+ };
3154
+ return await this.swapV2PrivatePostTradeMarginType(this.extend(request, params));
3155
+ }
3156
+ async setMargin(symbol, amount, params = {}) {
3157
+ /**
3158
+ * @method
3159
+ * @name bingx#setMargin
3160
+ * @description Either adds or reduces margin in an isolated position in order to set the margin to a specific value
3161
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Adjust%20isolated%20margin
3162
+ * @param {string} symbol unified market symbol of the market to set margin in
3163
+ * @param {float} amount the amount to set the margin to
3164
+ * @param {object} [params] parameters specific to the bingx api endpoint
3165
+ * @returns {object} A [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
3166
+ */
3167
+ const type = this.safeInteger(params, 'type'); // 1 increase margin 2 decrease margin
3168
+ if (type === undefined) {
3169
+ throw new errors.ArgumentsRequired(this.id + ' setMargin() requires a type parameter either 1 (increase margin) or 2 (decrease margin)');
3170
+ }
3171
+ if (!this.inArray(type, [1, 2])) {
3172
+ throw new errors.ArgumentsRequired(this.id + ' setMargin() requires a type parameter either 1 (increase margin) or 2 (decrease margin)');
3173
+ }
3174
+ await this.loadMarkets();
3175
+ const market = this.market(symbol);
3176
+ const request = {
3177
+ 'symbol': market['id'],
3178
+ 'amount': this.amountToPrecision(market['symbol'], amount),
3179
+ 'type': type,
3180
+ };
3181
+ const response = await this.swapV2PrivatePostTradePositionMargin(this.extend(request, params));
3182
+ //
3183
+ // {
3184
+ // "code": 0,
3185
+ // "msg": "",
3186
+ // "amount": 1,
3187
+ // "type": 1
3188
+ // }
3189
+ //
3190
+ return response;
3191
+ }
3192
+ async fetchLeverage(symbol, params = {}) {
3193
+ /**
3194
+ * @method
3195
+ * @name bingx#fetchLeverage
3196
+ * @description fetch the set leverage for a market
3197
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Query%20Leverage
3198
+ * @param {string} symbol unified market symbol
3199
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3200
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
3201
+ */
3202
+ await this.loadMarkets();
3203
+ const market = this.market(symbol);
3204
+ const request = {
3205
+ 'symbol': market['id'],
3206
+ };
3207
+ const response = await this.swapV2PrivateGetTradeLeverage(this.extend(request, params));
3208
+ //
3209
+ // {
3210
+ // "code": 0,
3211
+ // "msg": "",
3212
+ // "data": {
3213
+ // "longLeverage": 6,
3214
+ // "shortLeverage": 6
3215
+ // }
3216
+ // }
3217
+ //
3218
+ return response;
3219
+ }
3220
+ async setLeverage(leverage, symbol = undefined, params = {}) {
3221
+ /**
3222
+ * @method
3223
+ * @name bingx#setLeverage
3224
+ * @description set the level of leverage for a market
3225
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Switch%20Leverage
3226
+ * @param {float} leverage the rate of leverage
3227
+ * @param {string} symbol unified market symbol
3228
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3229
+ * @returns {object} response from the exchange
3230
+ */
3231
+ if (symbol === undefined) {
3232
+ throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
3233
+ }
3234
+ const side = this.safeStringUpper(params, 'side');
3235
+ this.checkRequiredArgument('setLeverage', side, 'side', ['LONG', 'SHORT']);
3236
+ await this.loadMarkets();
3237
+ const market = this.market(symbol);
3238
+ const request = {
3239
+ 'symbol': market['id'],
3240
+ 'side': side,
3241
+ 'leverage': leverage,
3242
+ };
3243
+ //
3244
+ // {
3245
+ // "code": 0,
3246
+ // "msg": "",
3247
+ // "data": {
3248
+ // "leverage": 6,
3249
+ // "symbol": "BTC-USDT"
3250
+ // }
3251
+ // }
3252
+ //
3253
+ return await this.swapV2PrivatePostTradeLeverage(this.extend(request, params));
3254
+ }
3255
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3256
+ /**
3257
+ * @method
3258
+ * @name bingx#fetchMyTrades
3259
+ * @description fetch all trades made by the user
3260
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Query%20historical%20transaction%20orders
3261
+ * @param {string} [symbol] unified market symbol
3262
+ * @param {int} [since] the earliest time in ms to fetch trades for
3263
+ * @param {int} [limit] the maximum number of trades structures to retrieve
3264
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3265
+ * @param {string} params.trandingUnit COIN (directly represent assets such as BTC and ETH) or CONT (represents the number of contract sheets)
3266
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
3267
+ */
3268
+ if (symbol === undefined) {
3269
+ throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
3270
+ }
3271
+ if (since === undefined) {
3272
+ throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a since argument');
3273
+ }
3274
+ const tradingUnit = this.safeStringUpper(params, 'tradingUnit', 'CONT');
3275
+ await this.loadMarkets();
3276
+ const market = this.market(symbol);
3277
+ if (market['spot']) {
3278
+ throw new errors.BadSymbol(this.id + ' fetchMyTrades() supports swap contracts only');
3279
+ }
3280
+ const request = {
3281
+ 'symbol': market['id'],
3282
+ 'tradingUnit': tradingUnit,
3283
+ 'startTs': since,
3284
+ 'endTs': this.nonce(),
3285
+ };
3286
+ const query = this.omit(params, 'tradingUnit');
3287
+ const response = await this.swapV2PrivateGetTradeAllFillOrders(this.extend(request, query));
3288
+ //
3289
+ // {
3290
+ // "code": "0",
3291
+ // "msg": '',
3292
+ // "data": { fill_orders: [
3293
+ // {
3294
+ // "volume": "0.1",
3295
+ // "price": "106.75",
3296
+ // "amount": "10.6750",
3297
+ // "commission": "-0.0053",
3298
+ // "currency": "USDT",
3299
+ // "orderId": "1676213270274379776",
3300
+ // "liquidatedPrice": "0.00",
3301
+ // "liquidatedMarginRatio": "0.00",
3302
+ // "filledTime": "2023-07-04T20:56:01.000+0800"
3303
+ // }
3304
+ // ]
3305
+ // }
3306
+ // }
3307
+ //
3308
+ const data = this.safeValue(response, 'data', []);
3309
+ const fillOrders = this.safeValue(data, 'fill_orders', []);
3310
+ return this.parseTrades(fillOrders, market, since, limit, query);
3311
+ }
3312
+ parseDepositWithdrawFee(fee, currency = undefined) {
3313
+ //
3314
+ // {
3315
+ // "coin": "BTC",
3316
+ // "name": "BTC",
3317
+ // "networkList": [
3318
+ // {
3319
+ // "name": "BTC",
3320
+ // "network": "BTC",
3321
+ // "isDefault": true,
3322
+ // "minConfirm": "2",
3323
+ // "withdrawEnable": true,
3324
+ // "withdrawFee": "0.00035",
3325
+ // "withdrawMax": "1.62842",
3326
+ // "withdrawMin": "0.0005"
3327
+ // },
3328
+ // {
3329
+ // "name": "BTC",
3330
+ // "network": "BEP20",
3331
+ // "isDefault": false,
3332
+ // "minConfirm": "15",
3333
+ // "withdrawEnable": true,
3334
+ // "withdrawFee": "0.00001",
3335
+ // "withdrawMax": "1.62734",
3336
+ // "withdrawMin": "0.0001"
3337
+ // }
3338
+ // ]
3339
+ // }
3340
+ //
3341
+ const networkList = this.safeValue(fee, 'networkList', []);
3342
+ const networkListLength = networkList.length;
3343
+ const result = {
3344
+ 'info': fee,
3345
+ 'withdraw': {
3346
+ 'fee': undefined,
3347
+ 'percentage': undefined,
3348
+ },
3349
+ 'deposit': {
3350
+ 'fee': undefined,
3351
+ 'percentage': undefined,
3352
+ },
3353
+ 'networks': {},
3354
+ };
3355
+ if (networkListLength !== 0) {
3356
+ for (let i = 0; i < networkListLength; i++) {
3357
+ const network = networkList[i];
3358
+ const networkId = this.safeString(network, 'network');
3359
+ const isDefault = this.safeValue(network, 'isDefault');
3360
+ const currencyCode = this.safeString(currency, 'code');
3361
+ const networkCode = this.networkIdToCode(networkId, currencyCode);
3362
+ result['networks'][networkCode] = {
3363
+ 'deposit': { 'fee': undefined, 'percentage': undefined },
3364
+ 'withdraw': { 'fee': this.safeNumber(network, 'withdrawFee'), 'percentage': false },
3365
+ };
3366
+ if (isDefault) {
3367
+ result['withdraw']['fee'] = this.safeNumber(network, 'withdrawFee');
3368
+ result['withdraw']['percentage'] = false;
3369
+ }
3370
+ }
3371
+ }
3372
+ return result;
3373
+ }
3374
+ async fetchDepositWithdrawFees(codes = undefined, params = {}) {
3375
+ /**
3376
+ * @method
3377
+ * @name bingx#fetchDepositWithdrawFees
3378
+ * @description fetch deposit and withdraw fees
3379
+ * @see https://bingx-api.github.io/docs/#/common/account-api.html#All%20Coins'%20Information
3380
+ * @param {string[]|undefined} codes list of unified currency codes
3381
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3382
+ * @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
3383
+ */
3384
+ await this.loadMarkets();
3385
+ const response = await this.walletsV1PrivateGetCapitalConfigGetall(params);
3386
+ const coins = this.safeValue(response, 'data');
3387
+ return this.parseDepositWithdrawFees(coins, codes, 'coin');
3388
+ }
3389
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
3390
+ /**
3391
+ * @method
3392
+ * @name bingx#withdraw
3393
+ * @description make a withdrawal
3394
+ * @see https://bingx-api.github.io/docs/#/common/account-api.html#Withdraw
3395
+ * @param {string} code unified currency code
3396
+ * @param {float} amount the amount to withdraw
3397
+ * @param {string} address the address to withdraw to
3398
+ * @param {string} [tag]
3399
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3400
+ * @param {int} [params.walletType] 1 fund account, 2 standard account, 3 perpetual account
3401
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
3402
+ */
3403
+ await this.loadMarkets();
3404
+ const currency = this.currency(code);
3405
+ let walletType = this.safeInteger(params, 'walletType');
3406
+ if (walletType === undefined) {
3407
+ walletType = 1;
3408
+ }
3409
+ if (!this.inArray(walletType, [1, 2, 3])) {
3410
+ throw new errors.BadRequest(this.id + ' withdraw() requires either 1 fund account, 2 standard futures account, 3 perpetual account for walletType');
3411
+ }
3412
+ const request = {
3413
+ 'coin': currency['id'],
3414
+ 'address': address,
3415
+ 'amount': this.numberToString(amount),
3416
+ 'walletType': walletType,
3417
+ };
3418
+ const network = this.safeStringUpper(params, 'network');
3419
+ if (network !== undefined) {
3420
+ request['network'] = this.networkCodeToId(network);
3421
+ }
3422
+ params = this.omit(params, ['walletType', 'network']);
3423
+ const response = await this.walletsV1PrivatePostCapitalWithdrawApply(this.extend(request, params));
3424
+ const data = this.safeValue(response, 'data');
3425
+ // {
3426
+ // "code":0,
3427
+ // "timestamp":1689258953651,
3428
+ // "data":{
3429
+ // "id":"1197073063359000577"
3430
+ // }
3431
+ // }
3432
+ this.parseTransaction(data);
3433
+ }
3434
+ parseParams(params) {
3435
+ const sortedParams = this.keysort(params);
3436
+ const keys = Object.keys(sortedParams);
3437
+ for (let i = 0; i < keys.length; i++) {
3438
+ const key = keys[i];
3439
+ const value = sortedParams[key];
3440
+ if (Array.isArray(value)) {
3441
+ let arrStr = '[';
3442
+ for (let j = 0; j < value.length; j++) {
3443
+ const arrayElement = value[j];
3444
+ if (j > 0) {
3445
+ arrStr += ',';
3446
+ }
3447
+ arrStr += arrayElement.toString();
3448
+ }
3449
+ arrStr += ']';
3450
+ sortedParams[key] = arrStr;
3451
+ }
3452
+ }
3453
+ return sortedParams;
3454
+ }
3455
+ async fetchMyLiquidations(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3456
+ /**
3457
+ * @method
3458
+ * @name bingx#fetchMyLiquidations
3459
+ * @description retrieves the users liquidated positions
3460
+ * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#User's%20Force%20Orders
3461
+ * @param {string} [symbol] unified CCXT market symbol
3462
+ * @param {int} [since] the earliest time in ms to fetch liquidations for
3463
+ * @param {int} [limit] the maximum number of liquidation structures to retrieve
3464
+ * @param {object} [params] exchange specific parameters for the bingx api endpoint
3465
+ * @param {int} [params.until] timestamp in ms of the latest liquidation
3466
+ * @returns {object} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure}
3467
+ */
3468
+ await this.loadMarkets();
3469
+ let request = {
3470
+ 'autoCloseType': 'LIQUIDATION',
3471
+ };
3472
+ [request, params] = this.handleUntilOption('endTime', request, params);
3473
+ let market = undefined;
3474
+ if (symbol !== undefined) {
3475
+ market = this.market(symbol);
3476
+ request['symbol'] = symbol;
3477
+ }
3478
+ if (since !== undefined) {
3479
+ request['startTime'] = since;
3480
+ }
3481
+ if (limit !== undefined) {
3482
+ request['limit'] = limit;
3483
+ }
3484
+ const response = await this.swapV2PrivateGetTradeForceOrders(this.extend(request, params));
3485
+ //
3486
+ // {
3487
+ // "code": 0,
3488
+ // "msg": "",
3489
+ // "data": {
3490
+ // "orders": [
3491
+ // {
3492
+ // "time": "int64",
3493
+ // "symbol": "string",
3494
+ // "side": "string",
3495
+ // "type": "string",
3496
+ // "positionSide": "string",
3497
+ // "cumQuote": "string",
3498
+ // "status": "string",
3499
+ // "stopPrice": "string",
3500
+ // "price": "string",
3501
+ // "origQty": "string",
3502
+ // "avgPrice": "string",
3503
+ // "executedQty": "string",
3504
+ // "orderId": "int64",
3505
+ // "profit": "string",
3506
+ // "commission": "string",
3507
+ // "workingType": "string",
3508
+ // "updateTime": "int64"
3509
+ // },
3510
+ // ]
3511
+ // }
3512
+ // }
3513
+ //
3514
+ const data = this.safeValue(response, 'data', {});
3515
+ const liquidations = this.safeValue(data, 'orders', []);
3516
+ return this.parseLiquidations(liquidations, market, since, limit);
3517
+ }
3518
+ parseLiquidation(liquidation, market = undefined) {
3519
+ //
3520
+ // {
3521
+ // "time": "int64",
3522
+ // "symbol": "string",
3523
+ // "side": "string",
3524
+ // "type": "string",
3525
+ // "positionSide": "string",
3526
+ // "cumQuote": "string",
3527
+ // "status": "string",
3528
+ // "stopPrice": "string",
3529
+ // "price": "string",
3530
+ // "origQty": "string",
3531
+ // "avgPrice": "string",
3532
+ // "executedQty": "string",
3533
+ // "orderId": "int64",
3534
+ // "profit": "string",
3535
+ // "commission": "string",
3536
+ // "workingType": "string",
3537
+ // "updateTime": "int64"
3538
+ // }
3539
+ //
3540
+ const marketId = this.safeString(liquidation, 'symbol');
3541
+ const timestamp = this.safeInteger(liquidation, 'time');
3542
+ const contractsString = this.safeString(liquidation, 'executedQty');
3543
+ const contractSizeString = this.safeString(market, 'contractSize');
3544
+ const priceString = this.safeString(liquidation, 'avgPrice');
3545
+ const baseValueString = Precise["default"].stringMul(contractsString, contractSizeString);
3546
+ const quoteValueString = Precise["default"].stringMul(baseValueString, priceString);
3547
+ return this.safeLiquidation({
3548
+ 'info': liquidation,
3549
+ 'symbol': this.safeSymbol(marketId, market),
3550
+ 'contracts': this.parseNumber(contractsString),
3551
+ 'contractSize': this.parseNumber(contractSizeString),
3552
+ 'price': this.parseNumber(priceString),
3553
+ 'baseValue': this.parseNumber(baseValueString),
3554
+ 'quoteValue': this.parseNumber(quoteValueString),
3555
+ 'timestamp': timestamp,
3556
+ 'datetime': this.iso8601(timestamp),
3557
+ });
3558
+ }
3559
+ async closePosition(symbol, side = undefined, params = {}) {
3560
+ /**
3561
+ * @method
3562
+ * @name bingx#closePosition
3563
+ * @description closes open positions for a market
3564
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#One-Click%20Close%20All%20Positions
3565
+ * @param {string} symbol Unified CCXT market symbol
3566
+ * @param {string} [side] not used by bingx
3567
+ * @param {object} [params] extra parameters specific to the bingx api endpoint
3568
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3569
+ */
3570
+ await this.loadMarkets();
3571
+ const market = this.market(symbol);
3572
+ const request = {
3573
+ 'symbol': market['id'],
3574
+ };
3575
+ const response = await this.swapV2PrivatePostTradeCloseAllPositions(this.extend(request, params));
3576
+ //
3577
+ // {
3578
+ // "code": 0,
3579
+ // "msg": "",
3580
+ // "data": {
3581
+ // "success": [
3582
+ // 1727686766700486656,
3583
+ // ],
3584
+ // "failed": null
3585
+ // }
3586
+ // }
3587
+ //
3588
+ const data = this.safeValue(response, 'data');
3589
+ return this.parseOrder(data);
3590
+ }
3591
+ async closeAllPositions(params = {}) {
3592
+ /**
3593
+ * @method
3594
+ * @name bitget#closePositions
3595
+ * @description closes open positions for a market
3596
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#One-Click%20Close%20All%20Positions
3597
+ * @param {object} [params] extra parameters specific to the okx api endpoint
3598
+ * @param {string} [params.recvWindow] request valid time window value
3599
+ * @returns {object[]} [A list of position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
3600
+ */
3601
+ await this.loadMarkets();
3602
+ const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
3603
+ const recvWindow = this.safeInteger(this.parseParams, 'recvWindow', defaultRecvWindow);
3604
+ let marketType = undefined;
3605
+ [marketType, params] = this.handleMarketTypeAndParams('closeAllPositions', undefined, params);
3606
+ if (marketType === 'margin') {
3607
+ throw new errors.BadRequest(this.id + ' closePositions () cannot be used for ' + marketType + ' markets');
3608
+ }
3609
+ const request = {
3610
+ 'recvWindow': recvWindow,
3611
+ };
3612
+ const response = await this.swapV2PrivatePostTradeCloseAllPositions(this.extend(request, params));
3613
+ //
3614
+ // {
3615
+ // "code": 0,
3616
+ // "msg": "",
3617
+ // "data": {
3618
+ // "success": [
3619
+ // 1727686766700486656,
3620
+ // 1727686767048613888
3621
+ // ],
3622
+ // "failed": null
3623
+ // }
3624
+ // }
3625
+ //
3626
+ const data = this.safeValue(response, 'data', {});
3627
+ const success = this.safeValue(data, 'success', []);
3628
+ const positions = [];
3629
+ for (let i = 0; i < success.length; i++) {
3630
+ const position = this.parsePosition({ 'positionId': success[i] });
3631
+ positions.push(position);
3632
+ }
3633
+ return positions;
3634
+ }
3635
+ async setPositionMode(hedged, symbol = undefined, params = {}) {
3636
+ /**
3637
+ * @method
3638
+ * @name bingx#setPositionMode
3639
+ * @description set hedged to true or false for a market
3640
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Set%20Position%20Mode
3641
+ * @param {bool} hedged set to true to use dualSidePosition
3642
+ * @param {string} symbol not used by bingx setPositionMode ()
3643
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3644
+ * @returns {object} response from the exchange
3645
+ */
3646
+ let dualSidePosition = undefined;
3647
+ if (hedged) {
3648
+ dualSidePosition = 'true';
3649
+ }
3650
+ else {
3651
+ dualSidePosition = 'false';
3652
+ }
3653
+ const request = {
3654
+ 'dualSidePosition': dualSidePosition,
3655
+ };
3656
+ //
3657
+ // {
3658
+ // code: '0',
3659
+ // msg: '',
3660
+ // timeStamp: '1703327432734',
3661
+ // data: { dualSidePosition: 'false' }
3662
+ // }
3663
+ //
3664
+ return await this.swapV1PrivatePostPositionSideDual(this.extend(request, params));
3665
+ }
3666
+ sign(path, section = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3667
+ const type = section[0];
3668
+ const version = section[1];
3669
+ const access = section[2];
3670
+ let url = this.implodeHostname(this.urls['api'][type]);
3671
+ if (type === 'spot' && version === 'v3') {
3672
+ url += '/api';
3673
+ }
3674
+ else {
3675
+ url += '/' + type;
3676
+ }
3677
+ url += '/' + version + '/';
3678
+ path = this.implodeParams(path, params);
3679
+ url += path;
3680
+ params = this.omit(params, this.extractParams(path));
3681
+ params = this.keysort(params);
3682
+ if (access === 'public') {
3683
+ params['timestamp'] = this.nonce();
3684
+ if (Object.keys(params).length) {
3685
+ url += '?' + this.urlencode(params);
3686
+ }
3687
+ }
3688
+ else if (access === 'private') {
3689
+ this.checkRequiredCredentials();
3690
+ params['timestamp'] = this.nonce();
3691
+ const parsedParams = this.parseParams(params);
3692
+ let query = this.urlencode(parsedParams);
3693
+ const signature = this.hmac(this.encode(this.rawencode(parsedParams)), this.encode(this.secret), sha256.sha256);
3694
+ if (Object.keys(params).length) {
3695
+ query = '?' + query + '&';
3696
+ }
3697
+ else {
3698
+ query += '?';
3699
+ }
3700
+ query += 'signature=' + signature;
3701
+ headers = {
3702
+ 'X-BX-APIKEY': this.apiKey,
3703
+ 'X-SOURCE-KEY': this.safeString(this.options, 'broker', 'CCXT'),
3704
+ };
3705
+ url += query;
3706
+ }
3707
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3708
+ }
3709
+ nonce() {
3710
+ return this.milliseconds();
3711
+ }
3712
+ handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3713
+ if (response === undefined) {
3714
+ return undefined; // fallback to default error handler
3715
+ }
3716
+ //
3717
+ // {
3718
+ // "code": 80014,
3719
+ // "msg": "Invalid parameters, err:Key: 'GetTickerRequest.Symbol' Error:Field validation for "Symbol" failed on the "len=0|endswith=-USDT" tag",
3720
+ // "data": {
3721
+ // }
3722
+ // }
3723
+ //
3724
+ const code = this.safeString(response, 'code');
3725
+ const message = this.safeString(response, 'msg');
3726
+ if (code !== undefined && code !== '0') {
3727
+ const feedback = this.id + ' ' + body;
3728
+ this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
3729
+ this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
3730
+ this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
3731
+ throw new errors.ExchangeError(feedback); // unknown message
3732
+ }
3733
+ return undefined;
3734
+ }
3735
+ }
3736
+
3737
+ module.exports = bingx;