ccxt 4.2.11 → 4.2.13

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 (392) hide show
  1. package/README.md +5 -5
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +1347 -490
  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 +2209 -0
  125. package/dist/cjs/js/src/binance.js +9736 -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 +3807 -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 +8291 -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 +3424 -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 +7072 -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 +9049 -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 +761 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2857 -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 +2851 -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 +7330 -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 +4722 -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 +1608 -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 +1867 -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 +2765 -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/bingx.d.ts +2 -0
  336. package/js/src/abstract/bybit.d.ts +1 -0
  337. package/js/src/abstract/gate.d.ts +11 -0
  338. package/js/src/abstract/gateio.d.ts +11 -0
  339. package/js/src/abstract/okx.d.ts +1 -0
  340. package/js/src/alpaca.js +18 -18
  341. package/js/src/base/Exchange.d.ts +5 -1
  342. package/js/src/base/Exchange.js +101 -12
  343. package/js/src/bigone.d.ts +3 -2
  344. package/js/src/bigone.js +429 -167
  345. package/js/src/binance.js +48 -34
  346. package/js/src/bingx.js +115 -38
  347. package/js/src/bitfinex.d.ts +2 -2
  348. package/js/src/bitfinex.js +2 -3
  349. package/js/src/bitget.js +33 -13
  350. package/js/src/bitmart.d.ts +2 -2
  351. package/js/src/bitmart.js +5 -5
  352. package/js/src/bitmex.js +1 -0
  353. package/js/src/bybit.js +2 -0
  354. package/js/src/coinbase.d.ts +26 -3
  355. package/js/src/coinbase.js +176 -26
  356. package/js/src/coinlist.js +3 -4
  357. package/js/src/coinone.js +1 -1
  358. package/js/src/coinsph.js +2 -3
  359. package/js/src/deribit.js +1 -0
  360. package/js/src/gate.d.ts +4 -4
  361. package/js/src/gate.js +96 -59
  362. package/js/src/gemini.js +1 -1
  363. package/js/src/hitbtc.d.ts +4 -4
  364. package/js/src/hitbtc.js +2 -3
  365. package/js/src/htx.d.ts +1 -0
  366. package/js/src/htx.js +29 -7
  367. package/js/src/huobijp.js +2 -3
  368. package/js/src/independentreserve.js +7 -5
  369. package/js/src/kraken.js +3 -6
  370. package/js/src/lbank.js +59 -33
  371. package/js/src/mexc.js +2 -1
  372. package/js/src/oceanex.js +1 -1
  373. package/js/src/okx.js +14 -3
  374. package/js/src/phemex.js +9 -2
  375. package/js/src/pro/binance.d.ts +2 -23
  376. package/js/src/pro/binance.js +58 -22
  377. package/js/src/pro/coinbase.d.ts +2 -2
  378. package/js/src/pro/coinbase.js +4 -1
  379. package/js/src/pro/coinbasepro.d.ts +2 -2
  380. package/js/src/pro/hitbtc.d.ts +2 -2
  381. package/js/src/pro/kraken.js +1 -1
  382. package/js/src/pro/okx.d.ts +1 -0
  383. package/js/src/pro/okx.js +52 -2
  384. package/js/src/pro/poloniex.d.ts +2 -2
  385. package/js/src/probit.js +4 -2
  386. package/js/src/upbit.d.ts +3 -101
  387. package/js/src/upbit.js +12 -12
  388. package/js/src/wavesexchange.js +1 -1
  389. package/js/src/woo.d.ts +2 -0
  390. package/js/src/woo.js +52 -0
  391. package/package.json +1 -1
  392. package/skip-tests.json +5 -0
@@ -0,0 +1,3115 @@
1
+ 'use strict';
2
+
3
+ var okcoin$1 = require('./abstract/okcoin.js');
4
+ var errors = require('./base/errors.js');
5
+ var Precise = require('./base/Precise.js');
6
+ var number = require('./base/functions/number.js');
7
+ var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * @class okcoin
13
+ * @augments Exchange
14
+ */
15
+ class okcoin extends okcoin$1 {
16
+ describe() {
17
+ return this.deepExtend(super.describe(), {
18
+ 'id': 'okcoin',
19
+ 'name': 'OKCoin',
20
+ 'countries': ['CN', 'US'],
21
+ 'version': 'v5',
22
+ // cheapest endpoint is 100 requests per 2 seconds
23
+ // 50 requests per second => 1000 / 50 = 20ms
24
+ 'rateLimit': 20,
25
+ 'pro': true,
26
+ 'has': {
27
+ 'CORS': undefined,
28
+ 'spot': true,
29
+ 'margin': false,
30
+ 'swap': false,
31
+ 'future': true,
32
+ 'option': undefined,
33
+ 'cancelOrder': true,
34
+ 'createMarketBuyOrderWithCost': true,
35
+ 'createMarketOrderWithCost': false,
36
+ 'createMarketSellOrderWithCost': false,
37
+ 'createOrder': true,
38
+ 'fetchBalance': true,
39
+ 'fetchBorrowInterest': false,
40
+ 'fetchBorrowRate': false,
41
+ 'fetchBorrowRateHistories': false,
42
+ 'fetchBorrowRateHistory': false,
43
+ 'fetchBorrowRates': false,
44
+ 'fetchBorrowRatesPerSymbol': false,
45
+ 'fetchClosedOrders': true,
46
+ 'fetchCurrencies': true,
47
+ 'fetchDepositAddress': true,
48
+ 'fetchDeposits': true,
49
+ 'fetchLedger': true,
50
+ 'fetchMarkets': true,
51
+ 'fetchMyTrades': true,
52
+ 'fetchOHLCV': true,
53
+ 'fetchOpenOrders': true,
54
+ 'fetchOrder': true,
55
+ 'fetchOrderBook': true,
56
+ 'fetchOrders': undefined,
57
+ 'fetchOrderTrades': true,
58
+ 'fetchPosition': false,
59
+ 'fetchPositions': false,
60
+ 'fetchTicker': true,
61
+ 'fetchTickers': true,
62
+ 'fetchTime': true,
63
+ 'fetchTrades': true,
64
+ 'fetchTransactions': undefined,
65
+ 'fetchWithdrawals': true,
66
+ 'reduceMargin': false,
67
+ 'repayCrossMargin': false,
68
+ 'repayIsolatedMargin': false,
69
+ 'setMargin': false,
70
+ 'transfer': true,
71
+ 'withdraw': true,
72
+ },
73
+ 'timeframes': {
74
+ '1m': '1m',
75
+ '3m': '3m',
76
+ '5m': '5m',
77
+ '15m': '15m',
78
+ '30m': '30m',
79
+ '1h': '1H',
80
+ '2h': '2H',
81
+ '4h': '4H',
82
+ '6h': '6H',
83
+ '12h': '12H',
84
+ '1d': '1D',
85
+ '1w': '1W',
86
+ '1M': '1M',
87
+ '3M': '3M',
88
+ },
89
+ 'hostname': 'okcoin.com',
90
+ 'urls': {
91
+ 'logo': 'https://user-images.githubusercontent.com/51840849/87295551-102fbf00-c50e-11ea-90a9-462eebba5829.jpg',
92
+ 'api': {
93
+ 'rest': 'https://www.{hostname}',
94
+ },
95
+ 'www': 'https://www.okcoin.com',
96
+ 'doc': 'https://www.okcoin.com/docs/en/',
97
+ 'fees': 'https://www.okcoin.com/coin-fees',
98
+ 'referral': 'https://www.okcoin.com/account/register?flag=activity&channelId=600001513',
99
+ 'test': {
100
+ 'rest': 'https://testnet.okex.com',
101
+ },
102
+ },
103
+ 'api': {
104
+ 'public': {
105
+ 'get': {
106
+ 'market/tickers': 1,
107
+ 'market/ticker': 1,
108
+ 'market/books': 1 / 2,
109
+ 'market/candles': 1 / 2,
110
+ 'market/history-candles': 1 / 2,
111
+ 'market/trades': 1 / 5,
112
+ 'market/history-trades': 2,
113
+ 'market/platform-24-volume': 10,
114
+ 'market/open-oracle': 50,
115
+ 'market/exchange-rate': 20,
116
+ 'public/instruments': 1,
117
+ 'public/time': 2,
118
+ },
119
+ },
120
+ 'private': {
121
+ 'get': {
122
+ // trade
123
+ 'trade/order': 1 / 3,
124
+ 'trade/orders-pending': 1 / 3,
125
+ 'trade/orders-history': 1 / 2,
126
+ 'trade/orders-history-archive': 1 / 2,
127
+ 'trade/fills': 1 / 3,
128
+ 'trade/fills-history': 2.2,
129
+ 'trade/fills-archive': 2,
130
+ 'trade/order-algo': 1,
131
+ 'trade/orders-algo-pending': 1,
132
+ 'trade/orders-algo-history': 1,
133
+ // rfq
134
+ 'otc/rfq/trade': 4,
135
+ 'otc/rfq/history': 4,
136
+ // account
137
+ 'account/balance': 2,
138
+ 'account/bills': 5 / 3,
139
+ 'account/bills-archive': 5 / 3,
140
+ 'account/config': 4,
141
+ 'account/max-size': 4,
142
+ 'account/max-avail-size': 4,
143
+ 'account/trade-fee': 4,
144
+ 'account/max-withdrawal': 4,
145
+ // funding or assets
146
+ 'asset/currencies': 5 / 3,
147
+ 'asset/balances': 5 / 3,
148
+ 'asset/asset-valuation': 10,
149
+ 'asset/transfer-state': 10,
150
+ 'asset/bills': 5 / 3,
151
+ 'asset/deposit-lightning': 5,
152
+ 'asset/deposit-address': 5 / 3,
153
+ 'asset/deposit-history': 5 / 3,
154
+ 'asset/withdrawal-history': 5 / 3,
155
+ 'asset/deposit-withdraw-status': 20,
156
+ // fiat
157
+ 'fiat/deposit-history': 5 / 3,
158
+ 'fiat-withdraw-history': 5 / 3,
159
+ 'fiat-channel': 5 / 3,
160
+ // sub-account
161
+ 'users/subaccount/list': 10,
162
+ 'users/subaccount/apiKey': 10,
163
+ 'account/subaccount/balances': 10,
164
+ 'asset/subaccount/balances': 10,
165
+ 'asset/subaccount/bills': 10,
166
+ },
167
+ 'post': {
168
+ // trade
169
+ 'trade/order': 1 / 3,
170
+ 'trade/batch-orders': 1 / 15,
171
+ 'trade/cancel-order': 1 / 3,
172
+ 'trade/cancel-batch-orders': 1 / 15,
173
+ 'trade/amend-order': 1 / 3,
174
+ 'trade/amend-batch-orders': 1 / 150,
175
+ 'trade/order-algo': 1,
176
+ 'trade/cancel-algos': 1,
177
+ 'trade/cancel-advance-algos': 1,
178
+ // rfq
179
+ 'otc/rfq/quote': 4,
180
+ 'otc/rfq/trade': 4,
181
+ // funding
182
+ 'asset/transfer': 4,
183
+ 'asset/withdrawal': 4,
184
+ 'asset/withdrawal-lightning': 4,
185
+ 'asset/withdrawal-cancel': 4,
186
+ // fiat
187
+ 'fiat/deposit': 5 / 3,
188
+ 'fiat/cancel-deposit': 5 / 3,
189
+ 'fiat/withdrawal': 5 / 3,
190
+ 'fiat/cancel-withdrawal': 5 / 3,
191
+ // sub-account
192
+ 'asset/subaccount/transfer': 10,
193
+ },
194
+ },
195
+ },
196
+ 'fees': {
197
+ 'trading': {
198
+ 'taker': 0.002,
199
+ 'maker': 0.001,
200
+ },
201
+ 'spot': {
202
+ 'taker': 0.0015,
203
+ 'maker': 0.0010,
204
+ },
205
+ },
206
+ 'requiredCredentials': {
207
+ 'apiKey': true,
208
+ 'secret': true,
209
+ 'password': true,
210
+ },
211
+ 'exceptions': {
212
+ 'exact': {
213
+ // Public error codes from 50000-53999
214
+ // General Class
215
+ '1': errors.ExchangeError,
216
+ '2': errors.ExchangeError,
217
+ '50000': errors.BadRequest,
218
+ '50001': errors.OnMaintenance,
219
+ '50002': errors.BadRequest,
220
+ '50004': errors.RequestTimeout,
221
+ '50005': errors.ExchangeNotAvailable,
222
+ '50006': errors.BadRequest,
223
+ '50007': errors.AccountSuspended,
224
+ '50008': errors.AuthenticationError,
225
+ '50009': errors.AccountSuspended,
226
+ '50010': errors.ExchangeError,
227
+ '50011': errors.RateLimitExceeded,
228
+ '50012': errors.ExchangeError,
229
+ '50013': errors.ExchangeNotAvailable,
230
+ '50014': errors.BadRequest,
231
+ '50015': errors.ExchangeError,
232
+ '50016': errors.ExchangeError,
233
+ '50017': errors.ExchangeError,
234
+ '50018': errors.ExchangeError,
235
+ '50019': errors.ExchangeError,
236
+ '50020': errors.ExchangeError,
237
+ '50021': errors.ExchangeError,
238
+ '50022': errors.ExchangeError,
239
+ '50023': errors.ExchangeError,
240
+ '50024': errors.BadRequest,
241
+ '50025': errors.ExchangeError,
242
+ '50026': errors.ExchangeNotAvailable,
243
+ '50027': errors.PermissionDenied,
244
+ '50028': errors.ExchangeError,
245
+ '50044': errors.BadRequest,
246
+ // API Class
247
+ '50100': errors.ExchangeError,
248
+ '50101': errors.AuthenticationError,
249
+ '50102': errors.InvalidNonce,
250
+ '50103': errors.AuthenticationError,
251
+ '50104': errors.AuthenticationError,
252
+ '50105': errors.AuthenticationError,
253
+ '50106': errors.AuthenticationError,
254
+ '50107': errors.AuthenticationError,
255
+ '50108': errors.ExchangeError,
256
+ '50109': errors.ExchangeError,
257
+ '50110': errors.PermissionDenied,
258
+ '50111': errors.AuthenticationError,
259
+ '50112': errors.AuthenticationError,
260
+ '50113': errors.AuthenticationError,
261
+ '50114': errors.AuthenticationError,
262
+ '50115': errors.BadRequest,
263
+ // Trade Class
264
+ '51000': errors.BadRequest,
265
+ '51001': errors.BadSymbol,
266
+ '51002': errors.BadSymbol,
267
+ '51003': errors.BadRequest,
268
+ '51004': errors.InvalidOrder,
269
+ '51005': errors.InvalidOrder,
270
+ '51006': errors.InvalidOrder,
271
+ '51007': errors.InvalidOrder,
272
+ '51008': errors.InsufficientFunds,
273
+ '51009': errors.AccountSuspended,
274
+ '51010': errors.AccountNotEnabled,
275
+ '51011': errors.InvalidOrder,
276
+ '51012': errors.BadSymbol,
277
+ '51014': errors.BadSymbol,
278
+ '51015': errors.BadSymbol,
279
+ '51016': errors.InvalidOrder,
280
+ '51017': errors.ExchangeError,
281
+ '51018': errors.ExchangeError,
282
+ '51019': errors.ExchangeError,
283
+ '51020': errors.InvalidOrder,
284
+ '51023': errors.ExchangeError,
285
+ '51024': errors.AccountSuspended,
286
+ '51025': errors.ExchangeError,
287
+ '51026': errors.BadSymbol,
288
+ '51046': errors.InvalidOrder,
289
+ '51047': errors.InvalidOrder,
290
+ '51031': errors.InvalidOrder,
291
+ '51100': errors.InvalidOrder,
292
+ '51102': errors.InvalidOrder,
293
+ '51103': errors.InvalidOrder,
294
+ '51108': errors.InvalidOrder,
295
+ '51109': errors.InvalidOrder,
296
+ '51110': errors.InvalidOrder,
297
+ '51111': errors.BadRequest,
298
+ '51112': errors.InvalidOrder,
299
+ '51113': errors.RateLimitExceeded,
300
+ '51115': errors.InvalidOrder,
301
+ '51116': errors.InvalidOrder,
302
+ '51117': errors.InvalidOrder,
303
+ '51118': errors.InvalidOrder,
304
+ '51119': errors.InsufficientFunds,
305
+ '51120': errors.InvalidOrder,
306
+ '51121': errors.InvalidOrder,
307
+ '51122': errors.InvalidOrder,
308
+ '51124': errors.InvalidOrder,
309
+ '51125': errors.InvalidOrder,
310
+ '51126': errors.InvalidOrder,
311
+ '51127': errors.InsufficientFunds,
312
+ '51128': errors.InvalidOrder,
313
+ '51129': errors.InvalidOrder,
314
+ '51130': errors.BadSymbol,
315
+ '51131': errors.InsufficientFunds,
316
+ '51132': errors.InvalidOrder,
317
+ '51133': errors.InvalidOrder,
318
+ '51134': errors.InvalidOrder,
319
+ '51135': errors.InvalidOrder,
320
+ '51136': errors.InvalidOrder,
321
+ '51137': errors.InvalidOrder,
322
+ '51138': errors.InvalidOrder,
323
+ '51139': errors.InvalidOrder,
324
+ '51156': errors.BadRequest,
325
+ '51159': errors.BadRequest,
326
+ '51162': errors.InvalidOrder,
327
+ '51163': errors.InvalidOrder,
328
+ '51166': errors.InvalidOrder,
329
+ '51174': errors.InvalidOrder,
330
+ '51201': errors.InvalidOrder,
331
+ '51202': errors.InvalidOrder,
332
+ '51203': errors.InvalidOrder,
333
+ '51204': errors.InvalidOrder,
334
+ '51205': errors.InvalidOrder,
335
+ '51250': errors.InvalidOrder,
336
+ '51251': errors.InvalidOrder,
337
+ '51252': errors.InvalidOrder,
338
+ '51253': errors.InvalidOrder,
339
+ '51254': errors.InvalidOrder,
340
+ '51255': errors.InvalidOrder,
341
+ '51256': errors.InvalidOrder,
342
+ '51257': errors.InvalidOrder,
343
+ '51258': errors.InvalidOrder,
344
+ '51259': errors.InvalidOrder,
345
+ '51260': errors.InvalidOrder,
346
+ '51261': errors.InvalidOrder,
347
+ '51262': errors.InvalidOrder,
348
+ '51263': errors.InvalidOrder,
349
+ '51264': errors.InvalidOrder,
350
+ '51265': errors.InvalidOrder,
351
+ '51267': errors.InvalidOrder,
352
+ '51268': errors.InvalidOrder,
353
+ '51269': errors.InvalidOrder,
354
+ '51270': errors.InvalidOrder,
355
+ '51271': errors.InvalidOrder,
356
+ '51272': errors.InvalidOrder,
357
+ '51273': errors.InvalidOrder,
358
+ '51274': errors.InvalidOrder,
359
+ '51275': errors.InvalidOrder,
360
+ '51276': errors.InvalidOrder,
361
+ '51277': errors.InvalidOrder,
362
+ '51278': errors.InvalidOrder,
363
+ '51279': errors.InvalidOrder,
364
+ '51280': errors.InvalidOrder,
365
+ '51321': errors.InvalidOrder,
366
+ '51322': errors.InvalidOrder,
367
+ '51323': errors.BadRequest,
368
+ '51324': errors.BadRequest,
369
+ '51325': errors.InvalidOrder,
370
+ '51327': errors.InvalidOrder,
371
+ '51328': errors.InvalidOrder,
372
+ '51329': errors.InvalidOrder,
373
+ '51330': errors.InvalidOrder,
374
+ '51400': errors.OrderNotFound,
375
+ '51401': errors.OrderNotFound,
376
+ '51402': errors.OrderNotFound,
377
+ '51403': errors.InvalidOrder,
378
+ '51404': errors.InvalidOrder,
379
+ '51405': errors.ExchangeError,
380
+ '51406': errors.ExchangeError,
381
+ '51407': errors.BadRequest,
382
+ '51408': errors.ExchangeError,
383
+ '51409': errors.ExchangeError,
384
+ '51410': errors.CancelPending,
385
+ '51500': errors.ExchangeError,
386
+ '51501': errors.ExchangeError,
387
+ '51502': errors.InsufficientFunds,
388
+ '51503': errors.ExchangeError,
389
+ '51506': errors.ExchangeError,
390
+ '51508': errors.ExchangeError,
391
+ '51509': errors.ExchangeError,
392
+ '51510': errors.ExchangeError,
393
+ '51511': errors.ExchangeError,
394
+ '51600': errors.ExchangeError,
395
+ '51601': errors.ExchangeError,
396
+ '51602': errors.ExchangeError,
397
+ '51603': errors.OrderNotFound,
398
+ '51732': errors.AuthenticationError,
399
+ '51733': errors.AuthenticationError,
400
+ '51734': errors.AuthenticationError,
401
+ '51735': errors.ExchangeError,
402
+ '51736': errors.InsufficientFunds,
403
+ // Data class
404
+ '52000': errors.ExchangeError,
405
+ // SPOT/MARGIN error codes 54000-54999
406
+ '54000': errors.ExchangeError,
407
+ '54001': errors.ExchangeError,
408
+ // FUNDING error codes 58000-58999
409
+ '58000': errors.ExchangeError,
410
+ '58001': errors.AuthenticationError,
411
+ '58002': errors.PermissionDenied,
412
+ '58003': errors.ExchangeError,
413
+ '58004': errors.AccountSuspended,
414
+ '58005': errors.ExchangeError,
415
+ '58006': errors.ExchangeError,
416
+ '58007': errors.ExchangeError,
417
+ '58100': errors.ExchangeError,
418
+ '58101': errors.AccountSuspended,
419
+ '58102': errors.RateLimitExceeded,
420
+ '58103': errors.ExchangeError,
421
+ '58104': errors.ExchangeError,
422
+ '58105': errors.ExchangeError,
423
+ '58106': errors.ExchangeError,
424
+ '58107': errors.ExchangeError,
425
+ '58108': errors.ExchangeError,
426
+ '58109': errors.ExchangeError,
427
+ '58110': errors.ExchangeError,
428
+ '58111': errors.ExchangeError,
429
+ '58112': errors.ExchangeError,
430
+ '58114': errors.ExchangeError,
431
+ '58115': errors.ExchangeError,
432
+ '58116': errors.ExchangeError,
433
+ '58117': errors.ExchangeError,
434
+ '58125': errors.BadRequest,
435
+ '58126': errors.BadRequest,
436
+ '58127': errors.BadRequest,
437
+ '58128': errors.BadRequest,
438
+ '58200': errors.ExchangeError,
439
+ '58201': errors.ExchangeError,
440
+ '58202': errors.ExchangeError,
441
+ '58203': errors.InvalidAddress,
442
+ '58204': errors.AccountSuspended,
443
+ '58205': errors.ExchangeError,
444
+ '58206': errors.ExchangeError,
445
+ '58207': errors.InvalidAddress,
446
+ '58208': errors.ExchangeError,
447
+ '58209': errors.ExchangeError,
448
+ '58210': errors.ExchangeError,
449
+ '58211': errors.ExchangeError,
450
+ '58212': errors.ExchangeError,
451
+ '58213': errors.AuthenticationError,
452
+ '58221': errors.BadRequest,
453
+ '58222': errors.BadRequest,
454
+ '58224': errors.BadRequest,
455
+ '58227': errors.BadRequest,
456
+ '58228': errors.BadRequest,
457
+ '58229': errors.InsufficientFunds,
458
+ '58300': errors.ExchangeError,
459
+ '58350': errors.InsufficientFunds,
460
+ // Account error codes 59000-59999
461
+ '59000': errors.ExchangeError,
462
+ '59001': errors.ExchangeError,
463
+ '59100': errors.ExchangeError,
464
+ '59101': errors.ExchangeError,
465
+ '59102': errors.ExchangeError,
466
+ '59103': errors.InsufficientFunds,
467
+ '59104': errors.ExchangeError,
468
+ '59105': errors.ExchangeError,
469
+ '59106': errors.ExchangeError,
470
+ '59107': errors.ExchangeError,
471
+ '59108': errors.InsufficientFunds,
472
+ '59109': errors.ExchangeError,
473
+ '59128': errors.InvalidOrder,
474
+ '59200': errors.InsufficientFunds,
475
+ '59201': errors.InsufficientFunds,
476
+ '59216': errors.BadRequest,
477
+ '59300': errors.ExchangeError,
478
+ '59301': errors.ExchangeError,
479
+ '59313': errors.ExchangeError,
480
+ '59401': errors.ExchangeError,
481
+ '59500': errors.ExchangeError,
482
+ '59501': errors.ExchangeError,
483
+ '59502': errors.ExchangeError,
484
+ '59503': errors.ExchangeError,
485
+ '59504': errors.ExchangeError,
486
+ '59505': errors.ExchangeError,
487
+ '59506': errors.ExchangeError,
488
+ '59507': errors.ExchangeError,
489
+ '59508': errors.AccountSuspended,
490
+ // WebSocket error Codes from 60000-63999
491
+ '60001': errors.AuthenticationError,
492
+ '60002': errors.AuthenticationError,
493
+ '60003': errors.AuthenticationError,
494
+ '60004': errors.AuthenticationError,
495
+ '60005': errors.AuthenticationError,
496
+ '60006': errors.InvalidNonce,
497
+ '60007': errors.AuthenticationError,
498
+ '60008': errors.AuthenticationError,
499
+ '60009': errors.AuthenticationError,
500
+ '60010': errors.AuthenticationError,
501
+ '60011': errors.AuthenticationError,
502
+ '60012': errors.BadRequest,
503
+ '60013': errors.BadRequest,
504
+ '60014': errors.RateLimitExceeded,
505
+ '60015': errors.NetworkError,
506
+ '60016': errors.ExchangeNotAvailable,
507
+ '60017': errors.BadRequest,
508
+ '60018': errors.BadRequest,
509
+ '60019': errors.BadRequest,
510
+ '63999': errors.ExchangeError,
511
+ '70010': errors.BadRequest,
512
+ '70013': errors.BadRequest,
513
+ '70016': errors.BadRequest, // Please specify your instrument settings for at least one instType.
514
+ },
515
+ 'broad': {
516
+ 'Internal Server Error': errors.ExchangeNotAvailable,
517
+ 'server error': errors.ExchangeNotAvailable, // {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"server error 1236805249","msg":"server error 1236805249"}
518
+ },
519
+ },
520
+ 'precisionMode': number.TICK_SIZE,
521
+ 'options': {
522
+ 'fetchOHLCV': {
523
+ 'type': 'Candles', // Candles or HistoryCandles
524
+ },
525
+ 'createMarketBuyOrderRequiresPrice': true,
526
+ 'fetchMarkets': ['spot'],
527
+ 'defaultType': 'spot',
528
+ 'accountsByType': {
529
+ 'classic': '1',
530
+ 'spot': '1',
531
+ 'funding': '6',
532
+ 'main': '6',
533
+ 'unified': '18',
534
+ },
535
+ 'accountsById': {
536
+ '1': 'spot',
537
+ '6': 'funding',
538
+ '18': 'unified',
539
+ },
540
+ 'auth': {
541
+ 'time': 'public',
542
+ 'currencies': 'private',
543
+ 'instruments': 'public',
544
+ 'rate': 'public',
545
+ '{instrument_id}/constituents': 'public',
546
+ },
547
+ 'warnOnFetchCurrenciesWithoutAuthorization': false,
548
+ 'defaultNetwork': 'ERC20',
549
+ 'networks': {
550
+ 'ERC20': 'Ethereum',
551
+ },
552
+ },
553
+ 'commonCurrencies': {
554
+ // OKEX refers to ERC20 version of Aeternity (AEToken)
555
+ 'AE': 'AET',
556
+ 'BOX': 'DefiBox',
557
+ 'HOT': 'Hydro Protocol',
558
+ 'HSR': 'HC',
559
+ 'MAG': 'Maggie',
560
+ 'SBTC': 'Super Bitcoin',
561
+ 'TRADE': 'Unitrade',
562
+ 'YOYO': 'YOYOW',
563
+ 'WIN': 'WinToken', // https://github.com/ccxt/ccxt/issues/5701
564
+ },
565
+ });
566
+ }
567
+ async fetchTime(params = {}) {
568
+ /**
569
+ * @method
570
+ * @name okcoin#fetchTime
571
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
572
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
573
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
574
+ */
575
+ const response = await this.publicGetPublicTime(params);
576
+ //
577
+ // {
578
+ // "iso": "2015-01-07T23:47:25.201Z",
579
+ // "epoch": 1420674445.201
580
+ // }
581
+ //
582
+ return this.parse8601(this.safeString(response, 'iso'));
583
+ }
584
+ async fetchMarkets(params = {}) {
585
+ /**
586
+ * @method
587
+ * @name okcoin#fetchMarkets
588
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-public-data-get-instruments
589
+ * @description retrieves data on all markets for okcoin
590
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
591
+ * @returns {object[]} an array of objects representing market data
592
+ */
593
+ const request = {
594
+ 'instType': 'SPOT',
595
+ };
596
+ const response = await this.publicGetPublicInstruments(this.extend(request, params));
597
+ const markets = this.safeValue(response, 'data', []);
598
+ return this.parseMarkets(markets);
599
+ }
600
+ parseMarket(market) {
601
+ //
602
+ // spot markets
603
+ //
604
+ // {
605
+ // "base_currency": "EOS",
606
+ // "instrument_id": "EOS-OKB",
607
+ // "min_size": "0.01",
608
+ // "quote_currency": "OKB",
609
+ // "size_increment": "0.000001",
610
+ // "tick_size": "0.0001"
611
+ // }
612
+ //
613
+ const id = this.safeString(market, 'instId');
614
+ let type = this.safeStringLower(market, 'instType');
615
+ if (type === 'futures') {
616
+ type = 'future';
617
+ }
618
+ const spot = (type === 'spot');
619
+ const future = (type === 'future');
620
+ const swap = (type === 'swap');
621
+ const option = (type === 'option');
622
+ const contract = swap || future || option;
623
+ const baseId = this.safeString(market, 'baseCcy');
624
+ const quoteId = this.safeString(market, 'quoteCcy');
625
+ const base = this.safeCurrencyCode(baseId);
626
+ const quote = this.safeCurrencyCode(quoteId);
627
+ const symbol = base + '/' + quote;
628
+ const tickSize = this.safeString(market, 'tickSz');
629
+ const fees = this.safeValue2(this.fees, type, 'trading', {});
630
+ let maxLeverage = this.safeString(market, 'lever', '1');
631
+ maxLeverage = Precise["default"].stringMax(maxLeverage, '1');
632
+ const maxSpotCost = this.safeNumber(market, 'maxMktSz');
633
+ return this.extend(fees, {
634
+ 'id': id,
635
+ 'symbol': symbol,
636
+ 'base': base,
637
+ 'quote': quote,
638
+ 'settle': undefined,
639
+ 'baseId': baseId,
640
+ 'quoteId': quoteId,
641
+ 'settleId': undefined,
642
+ 'type': type,
643
+ 'spot': spot,
644
+ 'margin': spot && (Precise["default"].stringGt(maxLeverage, '1')),
645
+ 'swap': false,
646
+ 'future': false,
647
+ 'option': false,
648
+ 'active': true,
649
+ 'contract': false,
650
+ 'linear': undefined,
651
+ 'inverse': undefined,
652
+ 'contractSize': contract ? this.safeNumber(market, 'ctVal') : undefined,
653
+ 'expiry': undefined,
654
+ 'expiryDatetime': undefined,
655
+ 'strike': undefined,
656
+ 'optionType': undefined,
657
+ 'created': this.safeInteger(market, 'listTime'),
658
+ 'precision': {
659
+ 'amount': this.safeNumber(market, 'lotSz'),
660
+ 'price': this.parseNumber(tickSize),
661
+ },
662
+ 'limits': {
663
+ 'leverage': {
664
+ 'min': this.parseNumber('1'),
665
+ 'max': this.parseNumber(maxLeverage),
666
+ },
667
+ 'amount': {
668
+ 'min': this.safeNumber(market, 'minSz'),
669
+ 'max': undefined,
670
+ },
671
+ 'price': {
672
+ 'min': undefined,
673
+ 'max': undefined,
674
+ },
675
+ 'cost': {
676
+ 'min': undefined,
677
+ 'max': contract ? undefined : maxSpotCost,
678
+ },
679
+ },
680
+ 'info': market,
681
+ });
682
+ }
683
+ safeNetwork(networkId) {
684
+ const networksById = {
685
+ 'Bitcoin': 'BTC',
686
+ 'Omni': 'OMNI',
687
+ 'TRON': 'TRC20',
688
+ };
689
+ return this.safeString(networksById, networkId, networkId);
690
+ }
691
+ async fetchCurrencies(params = {}) {
692
+ /**
693
+ * @method
694
+ * @name okcoin#fetchCurrencies
695
+ * @description fetches all available currencies on an exchange
696
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
697
+ * @returns {object} an associative dictionary of currencies
698
+ */
699
+ if (!this.checkRequiredCredentials(false)) {
700
+ if (this.options['warnOnFetchCurrenciesWithoutAuthorization']) {
701
+ throw new errors.ExchangeError(this.id + ' fetchCurrencies() is a private API endpoint that requires authentication with API keys. Set the API keys on the exchange instance or exchange.options["warnOnFetchCurrenciesWithoutAuthorization"] = false to suppress this warning message.');
702
+ }
703
+ return undefined;
704
+ }
705
+ else {
706
+ const response = await this.privateGetAssetCurrencies(params);
707
+ const data = this.safeValue(response, 'data', []);
708
+ const result = {};
709
+ const dataByCurrencyId = this.groupBy(data, 'ccy');
710
+ const currencyIds = Object.keys(dataByCurrencyId);
711
+ for (let i = 0; i < currencyIds.length; i++) {
712
+ const currencyId = currencyIds[i];
713
+ const currency = this.safeCurrency(currencyId);
714
+ const code = currency['code'];
715
+ const chains = dataByCurrencyId[currencyId];
716
+ const networks = {};
717
+ let currencyActive = false;
718
+ let depositEnabled = false;
719
+ let withdrawEnabled = false;
720
+ let maxPrecision = undefined;
721
+ for (let j = 0; j < chains.length; j++) {
722
+ const chain = chains[j];
723
+ const canDeposit = this.safeValue(chain, 'canDep');
724
+ depositEnabled = (canDeposit) ? canDeposit : depositEnabled;
725
+ const canWithdraw = this.safeValue(chain, 'canWd');
726
+ withdrawEnabled = (canWithdraw) ? canWithdraw : withdrawEnabled;
727
+ const canInternal = this.safeValue(chain, 'canInternal');
728
+ const active = (canDeposit && canWithdraw && canInternal) ? true : false;
729
+ currencyActive = (active) ? active : currencyActive;
730
+ const networkId = this.safeString(chain, 'chain');
731
+ if ((networkId !== undefined) && (networkId.indexOf('-') >= 0)) {
732
+ const parts = networkId.split('-');
733
+ const chainPart = this.safeString(parts, 1, networkId);
734
+ const networkCode = this.safeNetwork(chainPart);
735
+ const precision = this.parsePrecision(this.safeString(chain, 'wdTickSz'));
736
+ if (maxPrecision === undefined) {
737
+ maxPrecision = precision;
738
+ }
739
+ else {
740
+ maxPrecision = Precise["default"].stringMin(maxPrecision, precision);
741
+ }
742
+ networks[networkCode] = {
743
+ 'id': networkId,
744
+ 'network': networkCode,
745
+ 'active': active,
746
+ 'deposit': canDeposit,
747
+ 'withdraw': canWithdraw,
748
+ 'fee': this.safeNumber(chain, 'minFee'),
749
+ 'precision': this.parseNumber(precision),
750
+ 'limits': {
751
+ 'withdraw': {
752
+ 'min': this.safeNumber(chain, 'minWd'),
753
+ 'max': this.safeNumber(chain, 'maxWd'),
754
+ },
755
+ },
756
+ 'info': chain,
757
+ };
758
+ }
759
+ }
760
+ const firstChain = this.safeValue(chains, 0);
761
+ result[code] = {
762
+ 'info': chains,
763
+ 'code': code,
764
+ 'id': currencyId,
765
+ 'name': this.safeString(firstChain, 'name'),
766
+ 'active': currencyActive,
767
+ 'deposit': depositEnabled,
768
+ 'withdraw': withdrawEnabled,
769
+ 'fee': undefined,
770
+ 'precision': this.parseNumber(maxPrecision),
771
+ 'limits': {
772
+ 'amount': {
773
+ 'min': undefined,
774
+ 'max': undefined,
775
+ },
776
+ },
777
+ 'networks': networks,
778
+ };
779
+ }
780
+ return result;
781
+ }
782
+ }
783
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
784
+ /**
785
+ * @method
786
+ * @name okcoin#fetchOrderBook
787
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-order-book
788
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
789
+ * @param {string} symbol unified symbol of the market to fetch the order book for
790
+ * @param {int} [limit] the maximum amount of order book entries to return
791
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
792
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
793
+ */
794
+ await this.loadMarkets();
795
+ const market = this.market(symbol);
796
+ const request = {
797
+ 'instId': market['id'],
798
+ };
799
+ limit = (limit === undefined) ? 20 : limit;
800
+ if (limit !== undefined) {
801
+ request['sz'] = limit; // max 400
802
+ }
803
+ const response = await this.publicGetMarketBooks(this.extend(request, params));
804
+ //
805
+ // {
806
+ // "code": "0",
807
+ // "msg": "",
808
+ // "data": [
809
+ // {
810
+ // "asks": [
811
+ // ["0.07228","4.211619","0","2"], // price, amount, liquidated orders, total open orders
812
+ // ["0.0723","299.880364","0","2"],
813
+ // ["0.07231","3.72832","0","1"],
814
+ // ],
815
+ // "bids": [
816
+ // ["0.07221","18.5","0","1"],
817
+ // ["0.0722","18.5","0","1"],
818
+ // ["0.07219","0.505407","0","1"],
819
+ // ],
820
+ // "ts": "1621438475342"
821
+ // }
822
+ // ]
823
+ // }
824
+ //
825
+ const data = this.safeValue(response, 'data', []);
826
+ const first = this.safeValue(data, 0, {});
827
+ const timestamp = this.safeInteger(first, 'ts');
828
+ return this.parseOrderBook(first, symbol, timestamp);
829
+ }
830
+ parseTicker(ticker, market = undefined) {
831
+ //
832
+ // {
833
+ // "instType": "SPOT",
834
+ // "instId": "ETH-BTC",
835
+ // "last": "0.07319",
836
+ // "lastSz": "0.044378",
837
+ // "askPx": "0.07322",
838
+ // "askSz": "4.2",
839
+ // "bidPx": "0.0732",
840
+ // "bidSz": "6.050058",
841
+ // "open24h": "0.07801",
842
+ // "high24h": "0.07975",
843
+ // "low24h": "0.06019",
844
+ // "volCcy24h": "11788.887619",
845
+ // "vol24h": "167493.829229",
846
+ // "ts": "1621440583784",
847
+ // "sodUtc0": "0.07872",
848
+ // "sodUtc8": "0.07345"
849
+ // }
850
+ //
851
+ const timestamp = this.safeInteger(ticker, 'ts');
852
+ const marketId = this.safeString(ticker, 'instId');
853
+ market = this.safeMarket(marketId, market, '-');
854
+ const symbol = market['symbol'];
855
+ const last = this.safeString(ticker, 'last');
856
+ const open = this.safeString(ticker, 'open24h');
857
+ const spot = this.safeValue(market, 'spot', false);
858
+ const quoteVolume = spot ? this.safeString(ticker, 'volCcy24h') : undefined;
859
+ const baseVolume = this.safeString(ticker, 'vol24h');
860
+ const high = this.safeString(ticker, 'high24h');
861
+ const low = this.safeString(ticker, 'low24h');
862
+ return this.safeTicker({
863
+ 'symbol': symbol,
864
+ 'timestamp': timestamp,
865
+ 'datetime': this.iso8601(timestamp),
866
+ 'high': high,
867
+ 'low': low,
868
+ 'bid': this.safeString(ticker, 'bidPx'),
869
+ 'bidVolume': this.safeString(ticker, 'bidSz'),
870
+ 'ask': this.safeString(ticker, 'askPx'),
871
+ 'askVolume': this.safeString(ticker, 'askSz'),
872
+ 'vwap': undefined,
873
+ 'open': open,
874
+ 'close': last,
875
+ 'last': last,
876
+ 'previousClose': undefined,
877
+ 'change': undefined,
878
+ 'percentage': undefined,
879
+ 'average': undefined,
880
+ 'baseVolume': baseVolume,
881
+ 'quoteVolume': quoteVolume,
882
+ 'info': ticker,
883
+ }, market);
884
+ }
885
+ async fetchTicker(symbol, params = {}) {
886
+ /**
887
+ * @method
888
+ * @name okcoin#fetchTicker
889
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-ticker
890
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
891
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
892
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
893
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
894
+ */
895
+ await this.loadMarkets();
896
+ const market = this.market(symbol);
897
+ const request = {
898
+ 'instId': market['id'],
899
+ };
900
+ const response = await this.publicGetMarketTicker(this.extend(request, params));
901
+ const data = this.safeValue(response, 'data', []);
902
+ const first = this.safeValue(data, 0, {});
903
+ //
904
+ // {
905
+ // "code": "0",
906
+ // "msg": "",
907
+ // "data": [
908
+ // {
909
+ // "instType": "SPOT",
910
+ // "instId": "ETH-BTC",
911
+ // "last": "0.07319",
912
+ // "lastSz": "0.044378",
913
+ // "askPx": "0.07322",
914
+ // "askSz": "4.2",
915
+ // "bidPx": "0.0732",
916
+ // "bidSz": "6.050058",
917
+ // "open24h": "0.07801",
918
+ // "high24h": "0.07975",
919
+ // "low24h": "0.06019",
920
+ // "volCcy24h": "11788.887619",
921
+ // "vol24h": "167493.829229",
922
+ // "ts": "1621440583784",
923
+ // "sodUtc0": "0.07872",
924
+ // "sodUtc8": "0.07345"
925
+ // }
926
+ // ]
927
+ // }
928
+ //
929
+ return this.parseTicker(first, market);
930
+ }
931
+ async fetchTickers(symbols = undefined, params = {}) {
932
+ /**
933
+ * @method
934
+ * @name okcoin#fetchTickers
935
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-tickers
936
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
937
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
938
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
939
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
940
+ */
941
+ symbols = this.marketSymbols(symbols);
942
+ const request = {
943
+ 'instType': 'SPOT',
944
+ };
945
+ const response = await this.publicGetMarketTickers(this.extend(request, params));
946
+ const data = this.safeValue(response, 'data', []);
947
+ return this.parseTickers(data, symbols, params);
948
+ }
949
+ parseTrade(trade, market = undefined) {
950
+ //
951
+ // public fetchTrades
952
+ //
953
+ // {
954
+ // "instId": "ETH-BTC",
955
+ // "side": "sell",
956
+ // "sz": "0.119501",
957
+ // "px": "0.07065",
958
+ // "tradeId": "15826757",
959
+ // "ts": "1621446178316"
960
+ // }
961
+ //
962
+ // private fetchMyTrades
963
+ //
964
+ // {
965
+ // "side": "buy",
966
+ // "fillSz": "0.007533",
967
+ // "fillPx": "2654.98",
968
+ // "fee": "-0.000007533",
969
+ // "ordId": "317321390244397056",
970
+ // "instType": "SPOT",
971
+ // "instId": "ETH-USDT",
972
+ // "clOrdId": "",
973
+ // "posSide": "net",
974
+ // "billId": "317321390265368576",
975
+ // "tag": "0",
976
+ // "execType": "T",
977
+ // "tradeId": "107601752",
978
+ // "feeCcy": "ETH",
979
+ // "ts": "1621927314985"
980
+ // }
981
+ //
982
+ const id = this.safeString(trade, 'tradeId');
983
+ const marketId = this.safeString(trade, 'instId');
984
+ market = this.safeMarket(marketId, market, '-');
985
+ const symbol = market['symbol'];
986
+ const timestamp = this.safeInteger(trade, 'ts');
987
+ const price = this.safeString2(trade, 'fillPx', 'px');
988
+ const amount = this.safeString2(trade, 'fillSz', 'sz');
989
+ const side = this.safeString(trade, 'side');
990
+ const orderId = this.safeString(trade, 'ordId');
991
+ const feeCostString = this.safeString(trade, 'fee');
992
+ let fee = undefined;
993
+ if (feeCostString !== undefined) {
994
+ const feeCostSigned = Precise["default"].stringNeg(feeCostString);
995
+ const feeCurrencyId = this.safeString(trade, 'feeCcy');
996
+ const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
997
+ fee = {
998
+ 'cost': feeCostSigned,
999
+ 'currency': feeCurrencyCode,
1000
+ };
1001
+ }
1002
+ let takerOrMaker = this.safeString(trade, 'execType');
1003
+ if (takerOrMaker === 'T') {
1004
+ takerOrMaker = 'taker';
1005
+ }
1006
+ else if (takerOrMaker === 'M') {
1007
+ takerOrMaker = 'maker';
1008
+ }
1009
+ return this.safeTrade({
1010
+ 'info': trade,
1011
+ 'timestamp': timestamp,
1012
+ 'datetime': this.iso8601(timestamp),
1013
+ 'symbol': symbol,
1014
+ 'id': id,
1015
+ 'order': orderId,
1016
+ 'type': undefined,
1017
+ 'takerOrMaker': takerOrMaker,
1018
+ 'side': side,
1019
+ 'price': price,
1020
+ 'amount': amount,
1021
+ 'cost': undefined,
1022
+ 'fee': fee,
1023
+ }, market);
1024
+ }
1025
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1026
+ /**
1027
+ * @method
1028
+ * @name okcoin#fetchTrades
1029
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-trades
1030
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-trades-history
1031
+ * @description get the list of most recent trades for a particular symbol
1032
+ * @param {string} symbol unified symbol of the market to fetch trades for
1033
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1034
+ * @param {int} [limit] the maximum amount of trades to fetch
1035
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1036
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1037
+ */
1038
+ await this.loadMarkets();
1039
+ const market = this.market(symbol);
1040
+ if ((limit === undefined) || (limit > 100)) {
1041
+ limit = 100; // maximum = default = 100
1042
+ }
1043
+ const request = {
1044
+ 'instId': market['id'],
1045
+ };
1046
+ let method = undefined;
1047
+ [method, params] = this.handleOptionAndParams(params, 'fetchTrades', 'method', 'publicGetMarketTrades');
1048
+ let response = undefined;
1049
+ if (method === 'publicGetMarketTrades') {
1050
+ response = await this.publicGetMarketTrades(this.extend(request, params));
1051
+ }
1052
+ else {
1053
+ response = await this.publicGetMarketHistoryTrades(this.extend(request, params));
1054
+ }
1055
+ const data = this.safeValue(response, 'data', []);
1056
+ return this.parseTrades(data, market, since, limit);
1057
+ }
1058
+ parseOHLCV(ohlcv, market = undefined) {
1059
+ //
1060
+ // [
1061
+ // "1678928760000", // timestamp
1062
+ // "24341.4", // open
1063
+ // "24344", // high
1064
+ // "24313.2", // low
1065
+ // "24323", // close
1066
+ // "628", // contract volume
1067
+ // "2.5819", // base volume
1068
+ // "62800", // quote volume
1069
+ // "0" // candlestick state
1070
+ // ]
1071
+ //
1072
+ return [
1073
+ this.safeInteger(ohlcv, 0),
1074
+ this.safeNumber(ohlcv, 1),
1075
+ this.safeNumber(ohlcv, 2),
1076
+ this.safeNumber(ohlcv, 3),
1077
+ this.safeNumber(ohlcv, 4),
1078
+ this.safeNumber(ohlcv, 5),
1079
+ ];
1080
+ }
1081
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1082
+ /**
1083
+ * @method
1084
+ * @name okcoin#fetchOHLCV
1085
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-candlesticks
1086
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history
1087
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1088
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1089
+ * @param {string} timeframe the length of time each candle represents
1090
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
1091
+ * @param {int} [limit] the maximum amount of candles to fetch
1092
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1093
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1094
+ */
1095
+ await this.loadMarkets();
1096
+ const market = this.market(symbol);
1097
+ const duration = this.parseTimeframe(timeframe);
1098
+ const options = this.safeValue(this.options, 'fetchOHLCV', {});
1099
+ let bar = this.safeString(this.timeframes, timeframe, timeframe);
1100
+ const timezone = this.safeString(options, 'timezone', 'UTC');
1101
+ if ((timezone === 'UTC') && (duration >= 21600)) { // if utc and timeframe >= 6h
1102
+ bar += timezone.toLowerCase();
1103
+ }
1104
+ const request = {
1105
+ 'instId': market['id'],
1106
+ 'bar': bar,
1107
+ 'limit': limit,
1108
+ };
1109
+ let method = undefined;
1110
+ [method, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'method', 'publicGetMarketCandles');
1111
+ let response = undefined;
1112
+ if (method === 'publicGetMarketCandles') {
1113
+ response = await this.publicGetMarketCandles(this.extend(request, params));
1114
+ }
1115
+ else {
1116
+ response = await this.publicGetMarketHistoryCandles(this.extend(request, params));
1117
+ }
1118
+ const data = this.safeValue(response, 'data', []);
1119
+ return this.parseOHLCVs(data, market, timeframe, since, limit);
1120
+ }
1121
+ parseAccountBalance(response) {
1122
+ //
1123
+ // account
1124
+ //
1125
+ // [
1126
+ // {
1127
+ // "balance": 0,
1128
+ // "available": 0,
1129
+ // "currency": "BTC",
1130
+ // "hold": 0
1131
+ // },
1132
+ // {
1133
+ // "balance": 0,
1134
+ // "available": 0,
1135
+ // "currency": "ETH",
1136
+ // "hold": 0
1137
+ // }
1138
+ // ]
1139
+ //
1140
+ // spot
1141
+ //
1142
+ // [
1143
+ // {
1144
+ // "frozen": "0",
1145
+ // "hold": "0",
1146
+ // "id": "2149632",
1147
+ // "currency": "BTC",
1148
+ // "balance": "0.0000000497717339",
1149
+ // "available": "0.0000000497717339",
1150
+ // "holds": "0"
1151
+ // },
1152
+ // {
1153
+ // "frozen": "0",
1154
+ // "hold": "0",
1155
+ // "id": "2149632",
1156
+ // "currency": "ICN",
1157
+ // "balance": "0.00000000925",
1158
+ // "available": "0.00000000925",
1159
+ // "holds": "0"
1160
+ // }
1161
+ // ]
1162
+ //
1163
+ const result = {
1164
+ 'info': response,
1165
+ 'timestamp': undefined,
1166
+ 'datetime': undefined,
1167
+ };
1168
+ for (let i = 0; i < response.length; i++) {
1169
+ const balance = response[i];
1170
+ const currencyId = this.safeString(balance, 'currency');
1171
+ const code = this.safeCurrencyCode(currencyId);
1172
+ const account = this.account();
1173
+ account['total'] = this.safeString(balance, 'balance');
1174
+ account['used'] = this.safeString(balance, 'hold');
1175
+ account['free'] = this.safeString(balance, 'available');
1176
+ result[code] = account;
1177
+ }
1178
+ return this.safeBalance(result);
1179
+ }
1180
+ async fetchBalance(params = {}) {
1181
+ /**
1182
+ * @method
1183
+ * @name okcoin#fetchBalance
1184
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1185
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1186
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1187
+ */
1188
+ await this.loadMarkets();
1189
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
1190
+ const request = {
1191
+ // 'ccy': 'BTC,ETH', // comma-separated list of currency ids
1192
+ };
1193
+ let response = undefined;
1194
+ if (marketType === 'funding') {
1195
+ response = await this.privateGetAssetBalances(this.extend(request, query));
1196
+ }
1197
+ else {
1198
+ response = await this.privateGetAccountBalance(this.extend(request, query));
1199
+ }
1200
+ //
1201
+ // {
1202
+ // "code": "0",
1203
+ // "data": [
1204
+ // {
1205
+ // "category": "1",
1206
+ // "delivery": "",
1207
+ // "exercise": "",
1208
+ // "instType": "SPOT",
1209
+ // "level": "Lv1",
1210
+ // "maker": "-0.0008",
1211
+ // "taker": "-0.001",
1212
+ // "ts": "1639043138472"
1213
+ // }
1214
+ // ],
1215
+ // "msg": ""
1216
+ // }
1217
+ //
1218
+ if (marketType === 'funding') {
1219
+ return this.parseFundingBalance(response);
1220
+ }
1221
+ else {
1222
+ return this.parseTradingBalance(response);
1223
+ }
1224
+ }
1225
+ parseTradingBalance(response) {
1226
+ const result = { 'info': response };
1227
+ const data = this.safeValue(response, 'data', []);
1228
+ const first = this.safeValue(data, 0, {});
1229
+ const timestamp = this.safeInteger(first, 'uTime');
1230
+ const details = this.safeValue(first, 'details', []);
1231
+ for (let i = 0; i < details.length; i++) {
1232
+ const balance = details[i];
1233
+ const currencyId = this.safeString(balance, 'ccy');
1234
+ const code = this.safeCurrencyCode(currencyId);
1235
+ const account = this.account();
1236
+ // it may be incorrect to use total, free and used for swap accounts
1237
+ const eq = this.safeString(balance, 'eq');
1238
+ const availEq = this.safeString(balance, 'availEq');
1239
+ if ((eq === undefined) || (availEq === undefined)) {
1240
+ account['free'] = this.safeString(balance, 'availBal');
1241
+ account['used'] = this.safeString(balance, 'frozenBal');
1242
+ }
1243
+ else {
1244
+ account['total'] = eq;
1245
+ account['free'] = availEq;
1246
+ }
1247
+ result[code] = account;
1248
+ }
1249
+ result['timestamp'] = timestamp;
1250
+ result['datetime'] = this.iso8601(timestamp);
1251
+ return this.safeBalance(result);
1252
+ }
1253
+ parseFundingBalance(response) {
1254
+ const result = { 'info': response };
1255
+ const data = this.safeValue(response, 'data', []);
1256
+ for (let i = 0; i < data.length; i++) {
1257
+ const balance = data[i];
1258
+ const currencyId = this.safeString(balance, 'ccy');
1259
+ const code = this.safeCurrencyCode(currencyId);
1260
+ const account = this.account();
1261
+ // it may be incorrect to use total, free and used for swap accounts
1262
+ account['total'] = this.safeString(balance, 'bal');
1263
+ account['free'] = this.safeString(balance, 'availBal');
1264
+ account['used'] = this.safeString(balance, 'frozenBal');
1265
+ result[code] = account;
1266
+ }
1267
+ return this.safeBalance(result);
1268
+ }
1269
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1270
+ /**
1271
+ * @method
1272
+ * @name okcoin#createMarketBuyOrderWithCost
1273
+ * @description create a market buy order by providing the symbol and cost
1274
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
1275
+ * @param {string} symbol unified symbol of the market to create an order in
1276
+ * @param {float} cost how much you want to trade in units of the quote currency
1277
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1278
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1279
+ */
1280
+ await this.loadMarkets();
1281
+ const market = this.market(symbol);
1282
+ if (!market['spot']) {
1283
+ throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
1284
+ }
1285
+ params['createMarketBuyOrderRequiresPrice'] = false;
1286
+ params['tgtCcy'] = 'quote_ccy';
1287
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1288
+ }
1289
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1290
+ /**
1291
+ * @method
1292
+ * @name okcoin#createOrder
1293
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-order
1294
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-algo-order
1295
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-place-multiple-orders
1296
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
1297
+ * @description create a trade order
1298
+ * @param {string} symbol unified symbol of the market to create an order in
1299
+ * @param {string} type 'market' or 'limit'
1300
+ * @param {string} side 'buy' or 'sell'
1301
+ * @param {float} amount how much of currency you want to trade in units of base currency
1302
+ * @param {float} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1303
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1304
+ * @param {bool} [params.reduceOnly] MARGIN orders only, or swap/future orders in net mode
1305
+ * @param {bool} [params.postOnly] true to place a post only order
1306
+ * @param {float} [params.triggerPrice] conditional orders only, the price at which the order is to be triggered
1307
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only)
1308
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
1309
+ * @param {float} [params.takeProfit.price] used for take profit limit orders, not used for take profit market price orders
1310
+ * @param {string} [params.takeProfit.type] 'market' or 'limit' used to specify the take profit price type
1311
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only)
1312
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
1313
+ * @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders
1314
+ * @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type
1315
+ * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
1316
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1317
+ */
1318
+ await this.loadMarkets();
1319
+ const market = this.market(symbol);
1320
+ let request = this.createOrderRequest(symbol, type, side, amount, price, params);
1321
+ let method = this.safeString(this.options, 'createOrder', 'privatePostTradeBatchOrders');
1322
+ const requestOrdType = this.safeString(request, 'ordType');
1323
+ if ((requestOrdType === 'trigger') || (requestOrdType === 'conditional') || (type === 'oco') || (type === 'move_order_stop') || (type === 'iceberg') || (type === 'twap')) {
1324
+ method = 'privatePostTradeOrderAlgo';
1325
+ }
1326
+ if (method === 'privatePostTradeBatchOrders') {
1327
+ // keep the request body the same
1328
+ // submit a single order in an array to the batch order endpoint
1329
+ // because it has a lower ratelimit
1330
+ request = [request];
1331
+ }
1332
+ let response = undefined;
1333
+ if (method === 'privatePostTradeOrder') {
1334
+ response = await this.privatePostTradeOrder(request);
1335
+ }
1336
+ else if (method === 'privatePostTradeOrderAlgo') {
1337
+ response = await this.privatePostTradeOrderAlgo(request);
1338
+ }
1339
+ else if (method === 'privatePostTradeBatchOrders') {
1340
+ response = await this.privatePostTradeBatchOrders(request);
1341
+ }
1342
+ else {
1343
+ throw new errors.ExchangeError(this.id + ' createOrder() this.options["createOrder"] must be either privatePostTradeBatchOrders or privatePostTradeOrder or privatePostTradeOrderAlgo');
1344
+ }
1345
+ const data = this.safeValue(response, 'data', []);
1346
+ const first = this.safeValue(data, 0);
1347
+ const order = this.parseOrder(first, market);
1348
+ order['type'] = type;
1349
+ order['side'] = side;
1350
+ return order;
1351
+ }
1352
+ createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
1353
+ const market = this.market(symbol);
1354
+ const request = {
1355
+ 'instId': market['id'],
1356
+ // 'ccy': currency['id'], // only applicable to cross MARGIN orders in single-currency margin
1357
+ // 'clOrdId': clientOrderId, // up to 32 characters, must be unique
1358
+ // 'tag': tag, // up to 8 characters
1359
+ 'side': side,
1360
+ // 'posSide': 'long', // long, short, // required in the long/short mode, and can only be long or short (only for future or swap)
1361
+ 'ordType': type,
1362
+ // 'ordType': type, // privatePostTradeOrder: market, limit, post_only, fok, ioc, optimal_limit_ioc
1363
+ // 'ordType': type, // privatePostTradeOrderAlgo: conditional, oco, trigger, move_order_stop, iceberg, twap
1364
+ // 'sz': this.amountToPrecision (symbol, amount),
1365
+ // 'px': this.priceToPrecision (symbol, price), // limit orders only
1366
+ // 'reduceOnly': false,
1367
+ //
1368
+ // 'triggerPx': 10, // stopPrice (trigger orders)
1369
+ // 'orderPx': 10, // Order price if -1, the order will be executed at the market price. (trigger orders)
1370
+ // 'triggerPxType': 'last', // Conditional default is last, mark or index (trigger orders)
1371
+ //
1372
+ // 'tpTriggerPx': 10, // takeProfitPrice (conditional orders)
1373
+ // 'tpTriggerPxType': 'last', // Conditional default is last, mark or index (conditional orders)
1374
+ // 'tpOrdPx': 10, // Order price for Take-Profit orders, if -1 will be executed at market price (conditional orders)
1375
+ //
1376
+ // 'slTriggerPx': 10, // stopLossPrice (conditional orders)
1377
+ // 'slTriggerPxType': 'last', // Conditional default is last, mark or index (conditional orders)
1378
+ // 'slOrdPx': 10, // Order price for Stop-Loss orders, if -1 will be executed at market price (conditional orders)
1379
+ };
1380
+ const triggerPrice = this.safeValueN(params, ['triggerPrice', 'stopPrice', 'triggerPx']);
1381
+ const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
1382
+ const takeProfitPrice = this.safeValue2(params, 'takeProfitPrice', 'tpTriggerPx');
1383
+ const tpOrdPx = this.safeValue(params, 'tpOrdPx', price);
1384
+ const tpTriggerPxType = this.safeString(params, 'tpTriggerPxType', 'last');
1385
+ const stopLossPrice = this.safeValue2(params, 'stopLossPrice', 'slTriggerPx');
1386
+ const slOrdPx = this.safeValue(params, 'slOrdPx', price);
1387
+ const slTriggerPxType = this.safeString(params, 'slTriggerPxType', 'last');
1388
+ const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
1389
+ const stopLoss = this.safeValue(params, 'stopLoss');
1390
+ const stopLossDefined = (stopLoss !== undefined);
1391
+ const takeProfit = this.safeValue(params, 'takeProfit');
1392
+ const takeProfitDefined = (takeProfit !== undefined);
1393
+ const defaultMarginMode = this.safeString2(this.options, 'defaultMarginMode', 'marginMode', 'cross');
1394
+ let marginMode = this.safeString2(params, 'marginMode', 'tdMode'); // cross or isolated, tdMode not ommited so as to be extended into the request
1395
+ let margin = false;
1396
+ if ((marginMode !== undefined) && (marginMode !== 'cash')) {
1397
+ margin = true;
1398
+ }
1399
+ else {
1400
+ marginMode = defaultMarginMode;
1401
+ margin = this.safeValue(params, 'margin', false);
1402
+ }
1403
+ if (margin) {
1404
+ const defaultCurrency = (side === 'buy') ? market['quote'] : market['base'];
1405
+ const currency = this.safeString(params, 'ccy', defaultCurrency);
1406
+ request['ccy'] = this.safeCurrencyCode(currency);
1407
+ }
1408
+ const tradeMode = margin ? marginMode : 'cash';
1409
+ request['tdMode'] = tradeMode;
1410
+ const isMarketOrder = type === 'market';
1411
+ let postOnly = false;
1412
+ [postOnly, params] = this.handlePostOnly(isMarketOrder, type === 'post_only', params);
1413
+ params = this.omit(params, ['currency', 'ccy', 'marginMode', 'timeInForce', 'stopPrice', 'triggerPrice', 'clientOrderId', 'stopLossPrice', 'takeProfitPrice', 'slOrdPx', 'tpOrdPx', 'margin', 'stopLoss', 'takeProfit']);
1414
+ const ioc = (timeInForce === 'IOC') || (type === 'ioc');
1415
+ const fok = (timeInForce === 'FOK') || (type === 'fok');
1416
+ const trigger = (triggerPrice !== undefined) || (type === 'trigger');
1417
+ const conditional = (stopLossPrice !== undefined) || (takeProfitPrice !== undefined) || (type === 'conditional');
1418
+ const marketIOC = (isMarketOrder && ioc) || (type === 'optimal_limit_ioc');
1419
+ const defaultTgtCcy = this.safeString(this.options, 'tgtCcy', 'base_ccy');
1420
+ const tgtCcy = this.safeString(params, 'tgtCcy', defaultTgtCcy);
1421
+ if ((!margin)) {
1422
+ request['tgtCcy'] = tgtCcy;
1423
+ }
1424
+ if (isMarketOrder || marketIOC) {
1425
+ request['ordType'] = 'market';
1426
+ if (side === 'buy') {
1427
+ // spot market buy: "sz" can refer either to base currency units or to quote currency units
1428
+ // see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
1429
+ if (tgtCcy === 'quote_ccy') {
1430
+ // quote_ccy: sz refers to units of quote currency
1431
+ let quoteAmount = undefined;
1432
+ let createMarketBuyOrderRequiresPrice = true;
1433
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1434
+ const cost = this.safeNumber2(params, 'cost', 'sz');
1435
+ params = this.omit(params, ['cost', 'sz']);
1436
+ if (cost !== undefined) {
1437
+ quoteAmount = this.costToPrecision(symbol, cost);
1438
+ }
1439
+ else if (createMarketBuyOrderRequiresPrice) {
1440
+ if (price === undefined) {
1441
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend (quote quantity) in the amount argument');
1442
+ }
1443
+ else {
1444
+ const amountString = this.numberToString(amount);
1445
+ const priceString = this.numberToString(price);
1446
+ const costRequest = Precise["default"].stringMul(amountString, priceString);
1447
+ quoteAmount = this.costToPrecision(symbol, costRequest);
1448
+ }
1449
+ }
1450
+ else {
1451
+ quoteAmount = this.costToPrecision(symbol, amount);
1452
+ }
1453
+ request['sz'] = quoteAmount;
1454
+ }
1455
+ else {
1456
+ request['sz'] = this.amountToPrecision(symbol, amount);
1457
+ }
1458
+ }
1459
+ else {
1460
+ request['sz'] = this.amountToPrecision(symbol, amount);
1461
+ }
1462
+ }
1463
+ else {
1464
+ request['sz'] = this.amountToPrecision(symbol, amount);
1465
+ if ((!trigger) && (!conditional)) {
1466
+ request['px'] = this.priceToPrecision(symbol, price);
1467
+ }
1468
+ }
1469
+ if (postOnly) {
1470
+ request['ordType'] = 'post_only';
1471
+ }
1472
+ else if (ioc && !marketIOC) {
1473
+ request['ordType'] = 'ioc';
1474
+ }
1475
+ else if (fok) {
1476
+ request['ordType'] = 'fok';
1477
+ }
1478
+ else if (stopLossDefined || takeProfitDefined) {
1479
+ if (stopLossDefined) {
1480
+ const stopLossTriggerPrice = this.safeValueN(stopLoss, ['triggerPrice', 'stopPrice', 'slTriggerPx']);
1481
+ if (stopLossTriggerPrice === undefined) {
1482
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"], or params["stopLoss"]["stopPrice"], or params["stopLoss"]["slTriggerPx"] for a stop loss order');
1483
+ }
1484
+ request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
1485
+ const stopLossLimitPrice = this.safeValueN(stopLoss, ['price', 'stopLossPrice', 'slOrdPx']);
1486
+ const stopLossOrderType = this.safeString(stopLoss, 'type');
1487
+ if (stopLossOrderType !== undefined) {
1488
+ const stopLossLimitOrderType = (stopLossOrderType === 'limit');
1489
+ const stopLossMarketOrderType = (stopLossOrderType === 'market');
1490
+ if ((!stopLossLimitOrderType) && (!stopLossMarketOrderType)) {
1491
+ throw new errors.InvalidOrder(this.id + ' createOrder() params["stopLoss"]["type"] must be either "limit" or "market"');
1492
+ }
1493
+ else if (stopLossLimitOrderType) {
1494
+ if (stopLossLimitPrice === undefined) {
1495
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires a limit price in params["stopLoss"]["price"] or params["stopLoss"]["slOrdPx"] for a stop loss limit order');
1496
+ }
1497
+ else {
1498
+ request['slOrdPx'] = this.priceToPrecision(symbol, stopLossLimitPrice);
1499
+ }
1500
+ }
1501
+ else if (stopLossOrderType === 'market') {
1502
+ request['slOrdPx'] = '-1';
1503
+ }
1504
+ }
1505
+ else if (stopLossLimitPrice !== undefined) {
1506
+ request['slOrdPx'] = this.priceToPrecision(symbol, stopLossLimitPrice); // limit sl order
1507
+ }
1508
+ else {
1509
+ request['slOrdPx'] = '-1'; // market sl order
1510
+ }
1511
+ const stopLossTriggerPriceType = this.safeString2(stopLoss, 'triggerPriceType', 'slTriggerPxType', 'last');
1512
+ if (stopLossTriggerPriceType !== undefined) {
1513
+ if ((stopLossTriggerPriceType !== 'last') && (stopLossTriggerPriceType !== 'index') && (stopLossTriggerPriceType !== 'mark')) {
1514
+ throw new errors.InvalidOrder(this.id + ' createOrder() stop loss trigger price type must be one of "last", "index" or "mark"');
1515
+ }
1516
+ request['slTriggerPxType'] = stopLossTriggerPriceType;
1517
+ }
1518
+ }
1519
+ if (takeProfitDefined) {
1520
+ const takeProfitTriggerPrice = this.safeValueN(takeProfit, ['triggerPrice', 'stopPrice', 'tpTriggerPx']);
1521
+ if (takeProfitTriggerPrice === undefined) {
1522
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"], or params["takeProfit"]["stopPrice"], or params["takeProfit"]["tpTriggerPx"] for a take profit order');
1523
+ }
1524
+ request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
1525
+ const takeProfitLimitPrice = this.safeValueN(takeProfit, ['price', 'takeProfitPrice', 'tpOrdPx']);
1526
+ const takeProfitOrderType = this.safeString(takeProfit, 'type');
1527
+ if (takeProfitOrderType !== undefined) {
1528
+ const takeProfitLimitOrderType = (takeProfitOrderType === 'limit');
1529
+ const takeProfitMarketOrderType = (takeProfitOrderType === 'market');
1530
+ if ((!takeProfitLimitOrderType) && (!takeProfitMarketOrderType)) {
1531
+ throw new errors.InvalidOrder(this.id + ' createOrder() params["takeProfit"]["type"] must be either "limit" or "market"');
1532
+ }
1533
+ else if (takeProfitLimitOrderType) {
1534
+ if (takeProfitLimitPrice === undefined) {
1535
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires a limit price in params["takeProfit"]["price"] or params["takeProfit"]["tpOrdPx"] for a take profit limit order');
1536
+ }
1537
+ else {
1538
+ request['tpOrdPx'] = this.priceToPrecision(symbol, takeProfitLimitPrice);
1539
+ }
1540
+ }
1541
+ else if (takeProfitOrderType === 'market') {
1542
+ request['tpOrdPx'] = '-1';
1543
+ }
1544
+ }
1545
+ else if (takeProfitLimitPrice !== undefined) {
1546
+ request['tpOrdPx'] = this.priceToPrecision(symbol, takeProfitLimitPrice); // limit tp order
1547
+ }
1548
+ else {
1549
+ request['tpOrdPx'] = '-1'; // market tp order
1550
+ }
1551
+ const takeProfitTriggerPriceType = this.safeString2(takeProfit, 'triggerPriceType', 'tpTriggerPxType', 'last');
1552
+ if (takeProfitTriggerPriceType !== undefined) {
1553
+ if ((takeProfitTriggerPriceType !== 'last') && (takeProfitTriggerPriceType !== 'index') && (takeProfitTriggerPriceType !== 'mark')) {
1554
+ throw new errors.InvalidOrder(this.id + ' createOrder() take profit trigger price type must be one of "last", "index" or "mark"');
1555
+ }
1556
+ request['tpTriggerPxType'] = takeProfitTriggerPriceType;
1557
+ }
1558
+ }
1559
+ }
1560
+ else if (trigger) {
1561
+ request['ordType'] = 'trigger';
1562
+ request['triggerPx'] = this.priceToPrecision(symbol, triggerPrice);
1563
+ request['orderPx'] = isMarketOrder ? '-1' : this.priceToPrecision(symbol, price);
1564
+ }
1565
+ else if (conditional) {
1566
+ request['ordType'] = 'conditional';
1567
+ const twoWayCondition = ((takeProfitPrice !== undefined) && (stopLossPrice !== undefined));
1568
+ // if TP and SL are sent together
1569
+ // as ordType 'conditional' only stop-loss order will be applied
1570
+ if (twoWayCondition) {
1571
+ request['ordType'] = 'oco';
1572
+ }
1573
+ if (takeProfitPrice !== undefined) {
1574
+ request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitPrice);
1575
+ request['tpOrdPx'] = (tpOrdPx === undefined) ? '-1' : this.priceToPrecision(symbol, tpOrdPx);
1576
+ request['tpTriggerPxType'] = tpTriggerPxType;
1577
+ }
1578
+ if (stopLossPrice !== undefined) {
1579
+ request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossPrice);
1580
+ request['slOrdPx'] = (slOrdPx === undefined) ? '-1' : this.priceToPrecision(symbol, slOrdPx);
1581
+ request['slTriggerPxType'] = slTriggerPxType;
1582
+ }
1583
+ }
1584
+ if (clientOrderId === undefined) {
1585
+ const brokerId = this.safeString(this.options, 'brokerId');
1586
+ if (brokerId !== undefined) {
1587
+ request['clOrdId'] = brokerId + this.uuid16();
1588
+ request['tag'] = brokerId;
1589
+ }
1590
+ }
1591
+ else {
1592
+ request['clOrdId'] = clientOrderId;
1593
+ params = this.omit(params, ['clOrdId', 'clientOrderId']);
1594
+ }
1595
+ return this.extend(request, params);
1596
+ }
1597
+ async cancelOrder(id, symbol = undefined, params = {}) {
1598
+ /**
1599
+ * @method
1600
+ * @name okcoin#cancelOrder
1601
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-order
1602
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-algo-order
1603
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
1604
+ * @description cancels an open order
1605
+ * @param {string} id order id
1606
+ * @param {string} symbol unified symbol of the market the order was made in
1607
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1608
+ * @param {bool} [params.stop] True if cancel trigger or conditional orders
1609
+ * @param {bool} [params.advanced] True if canceling advanced orders only
1610
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1611
+ */
1612
+ if (symbol === undefined) {
1613
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
1614
+ }
1615
+ await this.loadMarkets();
1616
+ const stop = this.safeValue2(params, 'stop', 'trigger');
1617
+ const advanced = this.safeValue(params, 'advanced');
1618
+ if (stop || advanced) {
1619
+ const orderInner = await this.cancelOrders([id], symbol, params);
1620
+ return this.safeValue(orderInner, 0);
1621
+ }
1622
+ const market = this.market(symbol);
1623
+ const request = {
1624
+ 'instId': market['id'],
1625
+ // 'ordId': id, // either ordId or clOrdId is required
1626
+ // 'clOrdId': clientOrderId,
1627
+ };
1628
+ const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
1629
+ if (clientOrderId !== undefined) {
1630
+ request['clOrdId'] = clientOrderId;
1631
+ }
1632
+ else {
1633
+ request['ordId'] = id.toString();
1634
+ }
1635
+ const query = this.omit(params, ['clOrdId', 'clientOrderId']);
1636
+ const response = await this.privatePostTradeCancelOrder(this.extend(request, query));
1637
+ // {"code":"0","data":[{"clOrdId":"","ordId":"317251910906576896","sCode":"0","sMsg":""}],"msg":""}
1638
+ const data = this.safeValue(response, 'data', []);
1639
+ const order = this.safeValue(data, 0);
1640
+ return this.parseOrder(order, market);
1641
+ }
1642
+ parseIds(ids) {
1643
+ /**
1644
+ * @ignore
1645
+ * @method
1646
+ * @name okx#parseIds
1647
+ * @param {string[]|string} ids order ids
1648
+ * @returns {string[]} list of order ids
1649
+ */
1650
+ if (typeof ids === 'string') {
1651
+ return ids.split(',');
1652
+ }
1653
+ else {
1654
+ return ids;
1655
+ }
1656
+ }
1657
+ async cancelOrders(ids, symbol = undefined, params = {}) {
1658
+ /**
1659
+ * @method
1660
+ * @name okcoin#cancelOrders
1661
+ * @description cancel multiple orders
1662
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-multiple-orders
1663
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-algo-order
1664
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-cancel-advance-algo-order
1665
+ * @param {string[]} ids order ids
1666
+ * @param {string} symbol unified market symbol
1667
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1668
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1669
+ */
1670
+ if (symbol === undefined) {
1671
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
1672
+ }
1673
+ await this.loadMarkets();
1674
+ const stop = this.safeValue2(params, 'stop', 'trigger');
1675
+ const advanced = this.safeValue(params, 'advanced');
1676
+ params = this.omit(params, ['stop', 'trigger', 'advanced']);
1677
+ const market = this.market(symbol);
1678
+ const request = [];
1679
+ const clientOrderIds = this.parseIds(this.safeValue2(params, 'clOrdId', 'clientOrderId'));
1680
+ const algoIds = this.parseIds(this.safeValue(params, 'algoId'));
1681
+ if (clientOrderIds === undefined) {
1682
+ ids = this.parseIds(ids);
1683
+ if (algoIds !== undefined) {
1684
+ for (let i = 0; i < algoIds.length; i++) {
1685
+ request.push({
1686
+ 'algoId': algoIds[i],
1687
+ 'instId': market['id'],
1688
+ });
1689
+ }
1690
+ }
1691
+ for (let i = 0; i < ids.length; i++) {
1692
+ if (stop || advanced) {
1693
+ request.push({
1694
+ 'algoId': ids[i],
1695
+ 'instId': market['id'],
1696
+ });
1697
+ }
1698
+ else {
1699
+ request.push({
1700
+ 'ordId': ids[i],
1701
+ 'instId': market['id'],
1702
+ });
1703
+ }
1704
+ }
1705
+ }
1706
+ else {
1707
+ for (let i = 0; i < clientOrderIds.length; i++) {
1708
+ request.push({
1709
+ 'instId': market['id'],
1710
+ 'clOrdId': clientOrderIds[i],
1711
+ });
1712
+ }
1713
+ }
1714
+ let response = undefined;
1715
+ if (stop) {
1716
+ response = await this.privatePostTradeCancelAlgos(request);
1717
+ }
1718
+ else if (advanced) {
1719
+ response = await this.privatePostTradeCancelAdvanceAlgos(request);
1720
+ }
1721
+ else {
1722
+ response = await this.privatePostTradeCancelBatchOrders(request); // * dont extend with params, otherwise ARRAY will be turned into OBJECT
1723
+ }
1724
+ //
1725
+ // {
1726
+ // "code": "0",
1727
+ // "data": [
1728
+ // {
1729
+ // "clOrdId": "e123456789ec4dBC1123456ba123b45e",
1730
+ // "ordId": "405071912345641543",
1731
+ // "sCode": "0",
1732
+ // "sMsg": ""
1733
+ // },
1734
+ // ...
1735
+ // ],
1736
+ // "msg": ""
1737
+ // }
1738
+ //
1739
+ //
1740
+ const ordersData = this.safeValue(response, 'data', []);
1741
+ return this.parseOrders(ordersData, market, undefined, undefined, params);
1742
+ }
1743
+ parseOrderStatus(status) {
1744
+ const statuses = {
1745
+ 'canceled': 'canceled',
1746
+ 'live': 'open',
1747
+ 'partially_filled': 'open',
1748
+ 'filled': 'closed',
1749
+ 'effective': 'closed',
1750
+ };
1751
+ return this.safeString(statuses, status, status);
1752
+ }
1753
+ parseOrder(order, market = undefined) {
1754
+ //
1755
+ // createOrder
1756
+ //
1757
+ // {
1758
+ // "clOrdId": "oktswap6",
1759
+ // "ordId": "312269865356374016",
1760
+ // "tag": "",
1761
+ // "sCode": "0",
1762
+ // "sMsg": ""
1763
+ // }
1764
+ //
1765
+ // editOrder
1766
+ //
1767
+ // {
1768
+ // "clOrdId": "e847386590ce4dBCc1a045253497a547",
1769
+ // "ordId": "559176536793178112",
1770
+ // "reqId": "",
1771
+ // "sCode": "0",
1772
+ // "sMsg": ""
1773
+ // }
1774
+ //
1775
+ // Spot and Swap fetchOrder, fetchOpenOrders
1776
+ //
1777
+ // {
1778
+ // "accFillSz": "0",
1779
+ // "avgPx": "",
1780
+ // "cTime": "1621910749815",
1781
+ // "category": "normal",
1782
+ // "ccy": "",
1783
+ // "clOrdId": "",
1784
+ // "fee": "0",
1785
+ // "feeCcy": "ETH",
1786
+ // "fillPx": "",
1787
+ // "fillSz": "0",
1788
+ // "fillTime": "",
1789
+ // "instId": "ETH-USDT",
1790
+ // "instType": "SPOT",
1791
+ // "lever": "",
1792
+ // "ordId": "317251910906576896",
1793
+ // "ordType": "limit",
1794
+ // "pnl": "0",
1795
+ // "posSide": "net",
1796
+ // "px": "2000",
1797
+ // "rebate": "0",
1798
+ // "rebateCcy": "USDT",
1799
+ // "side": "buy",
1800
+ // "slOrdPx": "",
1801
+ // "slTriggerPx": "",
1802
+ // "state": "live",
1803
+ // "sz": "0.001",
1804
+ // "tag": "",
1805
+ // "tdMode": "cash",
1806
+ // "tpOrdPx": "",
1807
+ // "tpTriggerPx": "",
1808
+ // "tradeId": "",
1809
+ // "uTime": "1621910749815"
1810
+ // }
1811
+ //
1812
+ // Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders
1813
+ //
1814
+ // {
1815
+ // "activePx": "",
1816
+ // "activePxType": "",
1817
+ // "actualPx": "",
1818
+ // "actualSide": "buy",
1819
+ // "actualSz": "0",
1820
+ // "algoId": "431375349042380800",
1821
+ // "cTime": "1649119897778",
1822
+ // "callbackRatio": "",
1823
+ // "callbackSpread": "",
1824
+ // "ccy": "",
1825
+ // "ctVal": "0.01",
1826
+ // "instId": "BTC-USDT-SWAP",
1827
+ // "instType": "SWAP",
1828
+ // "last": "46538.9",
1829
+ // "lever": "125",
1830
+ // "moveTriggerPx": "",
1831
+ // "notionalUsd": "467.059",
1832
+ // "ordId": "",
1833
+ // "ordPx": "50000",
1834
+ // "ordType": "trigger",
1835
+ // "posSide": "long",
1836
+ // "pxLimit": "",
1837
+ // "pxSpread": "",
1838
+ // "pxVar": "",
1839
+ // "side": "buy",
1840
+ // "slOrdPx": "",
1841
+ // "slTriggerPx": "",
1842
+ // "slTriggerPxType": "",
1843
+ // "state": "live",
1844
+ // "sz": "1",
1845
+ // "szLimit": "",
1846
+ // "tag": "",
1847
+ // "tdMode": "isolated",
1848
+ // "tgtCcy": "",
1849
+ // "timeInterval": "",
1850
+ // "tpOrdPx": "",
1851
+ // "tpTriggerPx": "",
1852
+ // "tpTriggerPxType": "",
1853
+ // "triggerPx": "50000",
1854
+ // "triggerPxType": "last",
1855
+ // "triggerTime": "",
1856
+ // "uly": "BTC-USDT"
1857
+ // }
1858
+ //
1859
+ const id = this.safeString2(order, 'algoId', 'ordId');
1860
+ const timestamp = this.safeInteger(order, 'cTime');
1861
+ const lastUpdateTimestamp = this.safeInteger(order, 'uTime');
1862
+ const lastTradeTimestamp = this.safeInteger(order, 'fillTime');
1863
+ const side = this.safeString(order, 'side');
1864
+ let type = this.safeString(order, 'ordType');
1865
+ let postOnly = undefined;
1866
+ let timeInForce = undefined;
1867
+ if (type === 'post_only') {
1868
+ postOnly = true;
1869
+ type = 'limit';
1870
+ }
1871
+ else if (type === 'fok') {
1872
+ timeInForce = 'FOK';
1873
+ type = 'limit';
1874
+ }
1875
+ else if (type === 'ioc') {
1876
+ timeInForce = 'IOC';
1877
+ type = 'limit';
1878
+ }
1879
+ const marketId = this.safeString(order, 'instId');
1880
+ market = this.safeMarket(marketId, market);
1881
+ const symbol = this.safeSymbol(marketId, market, '-');
1882
+ const filled = this.safeString(order, 'accFillSz');
1883
+ const price = this.safeString2(order, 'px', 'ordPx');
1884
+ const average = this.safeString(order, 'avgPx');
1885
+ const status = this.parseOrderStatus(this.safeString(order, 'state'));
1886
+ const feeCostString = this.safeString(order, 'fee');
1887
+ let amount = undefined;
1888
+ let cost = undefined;
1889
+ // spot market buy: "sz" can refer either to base currency units or to quote currency units
1890
+ // see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order
1891
+ const defaultTgtCcy = this.safeString(this.options, 'tgtCcy', 'base_ccy');
1892
+ const tgtCcy = this.safeString(order, 'tgtCcy', defaultTgtCcy);
1893
+ if ((side === 'buy') && (type === 'market') && (tgtCcy === 'quote_ccy')) {
1894
+ // "sz" refers to the cost
1895
+ cost = this.safeString(order, 'sz');
1896
+ }
1897
+ else {
1898
+ // "sz" refers to the trade currency amount
1899
+ amount = this.safeString(order, 'sz');
1900
+ }
1901
+ let fee = undefined;
1902
+ if (feeCostString !== undefined) {
1903
+ const feeCostSigned = Precise["default"].stringNeg(feeCostString);
1904
+ const feeCurrencyId = this.safeString(order, 'feeCcy');
1905
+ const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
1906
+ fee = {
1907
+ 'cost': this.parseNumber(feeCostSigned),
1908
+ 'currency': feeCurrencyCode,
1909
+ };
1910
+ }
1911
+ let clientOrderId = this.safeString(order, 'clOrdId');
1912
+ if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {
1913
+ clientOrderId = undefined; // fix empty clientOrderId string
1914
+ }
1915
+ const stopLossPrice = this.safeNumber2(order, 'slTriggerPx', 'slOrdPx');
1916
+ const takeProfitPrice = this.safeNumber2(order, 'tpTriggerPx', 'tpOrdPx');
1917
+ const stopPrice = this.safeNumberN(order, ['triggerPx', 'moveTriggerPx']);
1918
+ const reduceOnlyRaw = this.safeString(order, 'reduceOnly');
1919
+ let reduceOnly = false;
1920
+ if (reduceOnly !== undefined) {
1921
+ reduceOnly = (reduceOnlyRaw === 'true');
1922
+ }
1923
+ return this.safeOrder({
1924
+ 'info': order,
1925
+ 'id': id,
1926
+ 'clientOrderId': clientOrderId,
1927
+ 'timestamp': timestamp,
1928
+ 'datetime': this.iso8601(timestamp),
1929
+ 'lastTradeTimestamp': lastTradeTimestamp,
1930
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
1931
+ 'symbol': symbol,
1932
+ 'type': type,
1933
+ 'timeInForce': timeInForce,
1934
+ 'postOnly': postOnly,
1935
+ 'side': side,
1936
+ 'price': price,
1937
+ 'stopLossPrice': stopLossPrice,
1938
+ 'takeProfitPrice': takeProfitPrice,
1939
+ 'stopPrice': stopPrice,
1940
+ 'triggerPrice': stopPrice,
1941
+ 'average': average,
1942
+ 'cost': cost,
1943
+ 'amount': amount,
1944
+ 'filled': filled,
1945
+ 'remaining': undefined,
1946
+ 'status': status,
1947
+ 'fee': fee,
1948
+ 'trades': undefined,
1949
+ 'reduceOnly': reduceOnly,
1950
+ }, market);
1951
+ }
1952
+ async fetchOrder(id, symbol = undefined, params = {}) {
1953
+ /**
1954
+ * @method
1955
+ * @name okcoin#fetchOrder
1956
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-details
1957
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-list
1958
+ * @description fetches information on an order made by the user
1959
+ * @param {string} symbol unified symbol of the market the order was made in
1960
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1961
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1962
+ */
1963
+ if (symbol === undefined) {
1964
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
1965
+ }
1966
+ await this.loadMarkets();
1967
+ const market = this.market(symbol);
1968
+ const request = {
1969
+ 'instId': market['id'],
1970
+ // 'clOrdId': 'abcdef12345', // optional, [a-z0-9]{1,32}
1971
+ // 'ordId': id,
1972
+ };
1973
+ const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
1974
+ const stop = this.safeValue2(params, 'stop', 'trigger');
1975
+ if (stop) {
1976
+ if (clientOrderId !== undefined) {
1977
+ request['algoClOrdId'] = clientOrderId;
1978
+ }
1979
+ else {
1980
+ request['algoId'] = id;
1981
+ }
1982
+ }
1983
+ else {
1984
+ if (clientOrderId !== undefined) {
1985
+ request['clOrdId'] = clientOrderId;
1986
+ }
1987
+ else {
1988
+ request['ordId'] = id;
1989
+ }
1990
+ }
1991
+ const query = this.omit(params, ['clientOrderId', 'stop', 'trigger']);
1992
+ let response = undefined;
1993
+ if (stop) {
1994
+ response = await this.privateGetTradeOrderAlgo(this.extend(request, query));
1995
+ }
1996
+ else {
1997
+ response = await this.privateGetTradeOrder(this.extend(request, query));
1998
+ }
1999
+ const data = this.safeValue(response, 'data', []);
2000
+ const order = this.safeValue(data, 0);
2001
+ return this.parseOrder(order);
2002
+ }
2003
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2004
+ /**
2005
+ * @method
2006
+ * @name okcoin#fetchOpenOrders
2007
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-list
2008
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-list
2009
+ * @description fetch all unfilled currently open orders
2010
+ * @param {string} symbol unified market symbol
2011
+ * @param {int} [since] the earliest time in ms to fetch open orders for
2012
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
2013
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2014
+ * @param {bool} [params.stop] True if fetching trigger or conditional orders
2015
+ * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
2016
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2017
+ */
2018
+ await this.loadMarkets();
2019
+ const request = {
2020
+ // 'instId': market['id'],
2021
+ // 'ordType': 'limit', // market, limit, post_only, fok, ioc, comma-separated, stop orders: conditional, oco, trigger, move_order_stop, iceberg, or twap
2022
+ // 'state': 'live', // live, partially_filled
2023
+ // 'after': orderId,
2024
+ // 'before': orderId,
2025
+ // 'limit': limit, // default 100, max 100
2026
+ };
2027
+ let market = undefined;
2028
+ if (symbol !== undefined) {
2029
+ market = this.market(symbol);
2030
+ request['instId'] = market['id'];
2031
+ }
2032
+ if (limit !== undefined) {
2033
+ request['limit'] = limit; // default 100, max 100
2034
+ }
2035
+ const ordType = this.safeString(params, 'ordType');
2036
+ const stop = this.safeValue(params, 'stop') || (this.safeString(params, 'ordType') !== undefined);
2037
+ if (stop && (ordType === undefined)) {
2038
+ request['ordType'] = 'trigger'; // default to trigger
2039
+ }
2040
+ params = this.omit(params, ['stop']);
2041
+ let response = undefined;
2042
+ if (stop) {
2043
+ response = await this.privateGetTradeOrdersAlgoPending(this.extend(request, params));
2044
+ }
2045
+ else {
2046
+ response = await this.privateGetTradeOrdersPending(this.extend(request, params));
2047
+ }
2048
+ const data = this.safeValue(response, 'data', []);
2049
+ return this.parseOrders(data, market, since, limit);
2050
+ }
2051
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2052
+ /**
2053
+ * @method
2054
+ * @name okcoin#fetchClosedOrders
2055
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-algo-order-history
2056
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-history-last-3-months
2057
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-order-history-last-7-days
2058
+ * @description fetches information on multiple closed orders made by the user
2059
+ * @param {string} symbol unified market symbol of the market orders were made in
2060
+ * @param {int} [since] the earliest time in ms to fetch orders for
2061
+ * @param {int} [limit] the maximum number of order structures to retrieve
2062
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2063
+ * @param {bool} [params.stop] True if fetching trigger or conditional orders
2064
+ * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
2065
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2066
+ */
2067
+ await this.loadMarkets();
2068
+ const request = {
2069
+ 'instType': 'SPOT',
2070
+ };
2071
+ let market = undefined;
2072
+ if (symbol !== undefined) {
2073
+ market = this.market(symbol);
2074
+ request['instId'] = market['id'];
2075
+ }
2076
+ const ordType = this.safeString(params, 'ordType');
2077
+ const stop = this.safeValue(params, 'stop') || (this.safeString(params, 'ordType') !== undefined);
2078
+ if (stop && (ordType === undefined)) {
2079
+ request['ordType'] = 'trigger'; // default to trigger
2080
+ }
2081
+ params = this.omit(params, ['stop']);
2082
+ let response = undefined;
2083
+ if (stop) {
2084
+ response = await this.privateGetTradeOrdersAlgoHistory(this.extend(request, params));
2085
+ }
2086
+ else {
2087
+ let method = undefined;
2088
+ [method, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'method', 'privateGetTradeOrdersHistory');
2089
+ if (method === 'privateGetTradeOrdersHistory') {
2090
+ response = await this.privateGetTradeOrdersHistory(this.extend(request, params));
2091
+ }
2092
+ else {
2093
+ response = await this.privateGetTradeOrdersHistoryArchive(this.extend(request, params));
2094
+ }
2095
+ }
2096
+ // {
2097
+ // "code": "0",
2098
+ // "data": [
2099
+ // {
2100
+ // "accFillSz": "0",
2101
+ // "avgPx": "",
2102
+ // "cTime": "1621910749815",
2103
+ // "category": "normal",
2104
+ // "ccy": "",
2105
+ // "clOrdId": "",
2106
+ // "fee": "0",
2107
+ // "feeCcy": "ETH",
2108
+ // "fillPx": "",
2109
+ // "fillSz": "0",
2110
+ // "fillTime": "",
2111
+ // "instId": "ETH-USDT",
2112
+ // "instType": "SPOT",
2113
+ // "lever": "",
2114
+ // "ordId": "317251910906576896",
2115
+ // "ordType": "limit",
2116
+ // "pnl": "0",
2117
+ // "posSide": "net",
2118
+ // "px":"20 00",
2119
+ // "rebate": "0",
2120
+ // "rebateCcy": "USDT",
2121
+ // "side": "buy",
2122
+ // "slOrdPx": "",
2123
+ // "slTriggerPx": "",
2124
+ // "state": "live",
2125
+ // "sz":"0. 001",
2126
+ // "tag": "",
2127
+ // "tdMode": "cash",
2128
+ // "tpOrdPx": "",
2129
+ // "tpTriggerPx": "",
2130
+ // "tradeId": "",
2131
+ // "uTime": "1621910749815"
2132
+ // }
2133
+ // ],
2134
+ // "msg":""
2135
+ // }
2136
+ //
2137
+ const data = this.safeValue(response, 'data', []);
2138
+ return this.parseOrders(data, market, since, limit);
2139
+ }
2140
+ parseDepositAddress(depositAddress, currency = undefined) {
2141
+ //
2142
+ // {
2143
+ // "addr": "okbtothemoon",
2144
+ // "memo": "971668", // may be missing
2145
+ // "tag":"52055", // may be missing
2146
+ // "pmtId": "", // may be missing
2147
+ // "ccy": "BTC",
2148
+ // "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account
2149
+ // "selected": true
2150
+ // }
2151
+ //
2152
+ // {
2153
+ // "ccy":"usdt-erc20",
2154
+ // "to":"6",
2155
+ // "addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa",
2156
+ // "selected":true
2157
+ // }
2158
+ //
2159
+ // {
2160
+ // "chain": "ETH-OKExChain",
2161
+ // "addrEx": { "comment": "6040348" }, // some currencies like TON may have this field,
2162
+ // "ctAddr": "72315c",
2163
+ // "ccy": "ETH",
2164
+ // "to": "6",
2165
+ // "addr": "0x1c9f2244d1ccaa060bd536827c18925db10db102",
2166
+ // "selected": true
2167
+ // }
2168
+ //
2169
+ const address = this.safeString(depositAddress, 'addr');
2170
+ let tag = this.safeStringN(depositAddress, ['tag', 'pmtId', 'memo']);
2171
+ if (tag === undefined) {
2172
+ const addrEx = this.safeValue(depositAddress, 'addrEx', {});
2173
+ tag = this.safeString(addrEx, 'comment');
2174
+ }
2175
+ const currencyId = this.safeString(depositAddress, 'ccy');
2176
+ currency = this.safeCurrency(currencyId, currency);
2177
+ const code = currency['code'];
2178
+ const chain = this.safeString(depositAddress, 'chain');
2179
+ const networkId = chain.replace(currencyId + '-', '');
2180
+ const network = this.networkIdToCode(networkId);
2181
+ // inconsistent naming responses from exchange
2182
+ // with respect to network naming provided in currency info vs address chain-names and ids
2183
+ //
2184
+ // response from address endpoint:
2185
+ // {
2186
+ // "chain": "USDT-Polygon",
2187
+ // "ctAddr": "",
2188
+ // "ccy": "USDT",
2189
+ // "to":"6" ,
2190
+ // "addr": "0x1903441e386cc49d937f6302955b5feb4286dcfa",
2191
+ // "selected": true
2192
+ // }
2193
+ // network information from currency['networks'] field:
2194
+ // Polygon: {
2195
+ // "info": {
2196
+ // "canDep": false,
2197
+ // "canInternal": false,
2198
+ // "canWd": false,
2199
+ // "ccy": "USDT",
2200
+ // "chain": "USDT-Polygon-Bridge",
2201
+ // "mainNet": false,
2202
+ // "maxFee": "26.879528",
2203
+ // "minFee": "13.439764",
2204
+ // "minWd": "0.001",
2205
+ // "name": ''
2206
+ // },
2207
+ // "id": "USDT-Polygon-Bridge",
2208
+ // "network": "Polygon",
2209
+ // "active": false,
2210
+ // "deposit": false,
2211
+ // "withdraw": false,
2212
+ // "fee": 13.439764,
2213
+ // "precision": undefined,
2214
+ // "limits": {
2215
+ // "withdraw": {
2216
+ // "min": 0.001,
2217
+ // "max": undefined
2218
+ // }
2219
+ // }
2220
+ // },
2221
+ //
2222
+ this.checkAddress(address);
2223
+ return {
2224
+ 'currency': code,
2225
+ 'address': address,
2226
+ 'tag': tag,
2227
+ 'network': network,
2228
+ 'info': depositAddress,
2229
+ };
2230
+ }
2231
+ async fetchDepositAddress(code, params = {}) {
2232
+ /**
2233
+ * @method
2234
+ * @name okx#fetchDepositAddress
2235
+ * @description fetch the deposit address for a currency associated with this account
2236
+ * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
2237
+ * @param {string} code unified currency code
2238
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2239
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
2240
+ */
2241
+ await this.loadMarkets();
2242
+ const defaultNetwork = this.safeString(this.options, 'defaultNetwork', 'ERC20');
2243
+ const networkId = this.safeString(params, 'network', defaultNetwork);
2244
+ const networkCode = this.networkIdToCode(networkId);
2245
+ params = this.omit(params, 'network');
2246
+ const response = await this.fetchDepositAddressesByNetwork(code, params);
2247
+ const result = this.safeValue(response, networkCode);
2248
+ if (result === undefined) {
2249
+ throw new errors.InvalidAddress(this.id + ' fetchDepositAddress() cannot find ' + networkCode + ' deposit address for ' + code);
2250
+ }
2251
+ return result;
2252
+ }
2253
+ async fetchDepositAddressesByNetwork(code, params = {}) {
2254
+ /**
2255
+ * @method
2256
+ * @name okx#fetchDepositAddressesByNetwork
2257
+ * @description fetch a dictionary of addresses for a currency, indexed by network
2258
+ * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
2259
+ * @param {string} code unified currency code of the currency for the deposit address
2260
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2261
+ * @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network
2262
+ */
2263
+ await this.loadMarkets();
2264
+ const currency = this.currency(code);
2265
+ const request = {
2266
+ 'ccy': currency['id'],
2267
+ };
2268
+ const response = await this.privateGetAssetDepositAddress(this.extend(request, params));
2269
+ //
2270
+ // {
2271
+ // "code": "0",
2272
+ // "msg": "",
2273
+ // "data": [
2274
+ // {
2275
+ // "addr": "okbtothemoon",
2276
+ // "memo": "971668", // may be missing
2277
+ // "tag":"52055", // may be missing
2278
+ // "pmtId": "", // may be missing
2279
+ // "ccy": "BTC",
2280
+ // "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account
2281
+ // "selected": true
2282
+ // },
2283
+ // // {"ccy":"usdt-erc20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
2284
+ // // {"ccy":"usdt-trc20","to":"6","addr":"TRrd5SiSZrfQVRKm4e9SRSbn2LNTYqCjqx","selected":true},
2285
+ // // {"ccy":"usdt_okexchain","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
2286
+ // // {"ccy":"usdt_kip20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true},
2287
+ // ]
2288
+ // }
2289
+ //
2290
+ const data = this.safeValue(response, 'data', []);
2291
+ const filtered = this.filterBy(data, 'selected', true);
2292
+ const parsed = this.parseDepositAddresses(filtered, [currency['code']], false);
2293
+ return this.indexBy(parsed, 'network');
2294
+ }
2295
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
2296
+ /**
2297
+ * @method
2298
+ * @name okcoin#transfer
2299
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-funds-transfer
2300
+ * @description transfer currency internally between wallets on the same account
2301
+ * @param {string} code unified currency code
2302
+ * @param {float} amount amount to transfer
2303
+ * @param {string} fromAccount account to transfer from
2304
+ * @param {string} toAccount account to transfer to
2305
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2306
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2307
+ */
2308
+ await this.loadMarkets();
2309
+ const currency = this.currency(code);
2310
+ const accountsByType = this.safeValue(this.options, 'accountsByType', {});
2311
+ const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
2312
+ const toId = this.safeString(accountsByType, toAccount, toAccount);
2313
+ const request = {
2314
+ 'ccy': currency['id'],
2315
+ 'amt': this.currencyToPrecision(code, amount),
2316
+ 'type': '0',
2317
+ 'from': fromId,
2318
+ 'to': toId, // beneficiary account, 6: Funding account, 18: Trading account
2319
+ // 'subAcct': 'sub-account-name', // optional, only required when type is 1, 2 or 4
2320
+ // 'loanTrans': false, // Whether or not borrowed coins can be transferred out under Multi-currency margin and Portfolio margin. The default is false
2321
+ // 'clientId': 'client-supplied id', // A combination of case-sensitive alphanumerics, all numbers, or all letters of up to 32 characters
2322
+ // 'omitPosRisk': false, // Ignore position risk. Default is false. Applicable to Portfolio margin
2323
+ };
2324
+ if (fromId === 'master') {
2325
+ request['type'] = '1';
2326
+ request['subAcct'] = toId;
2327
+ request['from'] = this.safeString(params, 'from', '6');
2328
+ request['to'] = this.safeString(params, 'to', '6');
2329
+ }
2330
+ else if (toId === 'master') {
2331
+ request['type'] = '2';
2332
+ request['subAcct'] = fromId;
2333
+ request['from'] = this.safeString(params, 'from', '6');
2334
+ request['to'] = this.safeString(params, 'to', '6');
2335
+ }
2336
+ const response = await this.privatePostAssetTransfer(this.extend(request, params));
2337
+ //
2338
+ // {
2339
+ // "code": "0",
2340
+ // "msg": "",
2341
+ // "data": [
2342
+ // {
2343
+ // "transId": "754147",
2344
+ // "ccy": "USDT",
2345
+ // "from": "6",
2346
+ // "amt": "0.1",
2347
+ // "to": "18"
2348
+ // }
2349
+ // ]
2350
+ // }
2351
+ //
2352
+ const data = this.safeValue(response, 'data', []);
2353
+ const rawTransfer = this.safeValue(data, 0, {});
2354
+ return this.parseTransfer(rawTransfer, currency);
2355
+ }
2356
+ parseTransfer(transfer, currency = undefined) {
2357
+ //
2358
+ // transfer
2359
+ //
2360
+ // {
2361
+ // "transId": "754147",
2362
+ // "ccy": "USDT",
2363
+ // "from": "6",
2364
+ // "amt": "0.1",
2365
+ // "to": "18"
2366
+ // }
2367
+ //
2368
+ // fetchTransfer
2369
+ //
2370
+ // {
2371
+ // "amt": "5",
2372
+ // "ccy": "USDT",
2373
+ // "from": "18",
2374
+ // "instId": "",
2375
+ // "state": "success",
2376
+ // "subAcct": "",
2377
+ // "to": "6",
2378
+ // "toInstId": "",
2379
+ // "transId": "464424732",
2380
+ // "type": "0"
2381
+ // }
2382
+ //
2383
+ // fetchTransfers
2384
+ //
2385
+ // {
2386
+ // "bal": "70.6874353780312913",
2387
+ // "balChg": "-4.0000000000000000", // negative means "to funding", positive meand "from funding"
2388
+ // "billId": "588900695232225299",
2389
+ // "ccy": "USDT",
2390
+ // "execType": "",
2391
+ // "fee": "",
2392
+ // "from": "18",
2393
+ // "instId": "",
2394
+ // "instType": "",
2395
+ // "mgnMode": "",
2396
+ // "notes": "To Funding Account",
2397
+ // "ordId": "",
2398
+ // "pnl": "",
2399
+ // "posBal": "",
2400
+ // "posBalChg": "",
2401
+ // "price": "0",
2402
+ // "subType": "12",
2403
+ // "sz": "-4",
2404
+ // "to": "6",
2405
+ // "ts": "1686676866989",
2406
+ // "type": "1"
2407
+ // }
2408
+ //
2409
+ const id = this.safeString2(transfer, 'transId', 'billId');
2410
+ const currencyId = this.safeString(transfer, 'ccy');
2411
+ const code = this.safeCurrencyCode(currencyId, currency);
2412
+ let amount = this.safeNumber(transfer, 'amt');
2413
+ const fromAccountId = this.safeString(transfer, 'from');
2414
+ const toAccountId = this.safeString(transfer, 'to');
2415
+ const accountsById = this.safeValue(this.options, 'accountsById', {});
2416
+ const timestamp = this.safeInteger(transfer, 'ts', this.milliseconds());
2417
+ const balanceChange = this.safeString(transfer, 'sz');
2418
+ if (balanceChange !== undefined) {
2419
+ amount = this.parseNumber(Precise["default"].stringAbs(balanceChange));
2420
+ }
2421
+ return {
2422
+ 'info': transfer,
2423
+ 'id': id,
2424
+ 'timestamp': timestamp,
2425
+ 'datetime': this.iso8601(timestamp),
2426
+ 'currency': code,
2427
+ 'amount': amount,
2428
+ 'fromAccount': this.safeString(accountsById, fromAccountId),
2429
+ 'toAccount': this.safeString(accountsById, toAccountId),
2430
+ 'status': this.parseTransferStatus(this.safeString(transfer, 'state')),
2431
+ };
2432
+ }
2433
+ parseTransferStatus(status) {
2434
+ const statuses = {
2435
+ 'success': 'ok',
2436
+ };
2437
+ return this.safeString(statuses, status, status);
2438
+ }
2439
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
2440
+ /**
2441
+ * @method
2442
+ * @name okcoin#withdraw
2443
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-withdrawal
2444
+ * @description make a withdrawal
2445
+ * @param {string} code unified currency code
2446
+ * @param {float} amount the amount to withdraw
2447
+ * @param {string} address the address to withdraw to
2448
+ * @param {string} tag
2449
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2450
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2451
+ */
2452
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
2453
+ this.checkAddress(address);
2454
+ await this.loadMarkets();
2455
+ const currency = this.currency(code);
2456
+ if ((tag !== undefined) && (tag.length > 0)) {
2457
+ address = address + ':' + tag;
2458
+ }
2459
+ const request = {
2460
+ 'ccy': currency['id'],
2461
+ 'toAddr': address,
2462
+ 'dest': '4',
2463
+ 'amt': this.numberToString(amount),
2464
+ };
2465
+ let network = this.safeString(params, 'network'); // this line allows the user to specify either ERC20 or ETH
2466
+ if (network !== undefined) {
2467
+ const networks = this.safeValue(this.options, 'networks', {});
2468
+ network = this.safeString(networks, network.toUpperCase(), network); // handle ETH>ERC20 alias
2469
+ request['chain'] = currency['id'] + '-' + network;
2470
+ params = this.omit(params, 'network');
2471
+ }
2472
+ let fee = this.safeString(params, 'fee');
2473
+ if (fee === undefined) {
2474
+ const targetNetwork = this.safeValue(currency['networks'], this.networkIdToCode(network), {});
2475
+ fee = this.safeString(targetNetwork, 'fee');
2476
+ if (fee === undefined) {
2477
+ throw new errors.ArgumentsRequired(this.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.');
2478
+ }
2479
+ }
2480
+ request['fee'] = this.numberToString(fee); // withdrawals to OKCoin or OKX are fee-free, please set 0
2481
+ const response = await this.privatePostAssetWithdrawal(this.extend(request, params));
2482
+ //
2483
+ // {
2484
+ // "code": "0",
2485
+ // "msg": "",
2486
+ // "data": [
2487
+ // {
2488
+ // "amt": "0.1",
2489
+ // "wdId": "67485",
2490
+ // "ccy": "BTC"
2491
+ // }
2492
+ // ]
2493
+ // }
2494
+ //
2495
+ const data = this.safeValue(response, 'data', []);
2496
+ const transaction = this.safeValue(data, 0);
2497
+ return this.parseTransaction(transaction, currency);
2498
+ }
2499
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
2500
+ /**
2501
+ * @method
2502
+ * @name okcoin#fetchDeposits
2503
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-get-deposit-history
2504
+ * @description fetch all deposits made to an account
2505
+ * @param {string} code unified currency code
2506
+ * @param {int} [since] the earliest time in ms to fetch deposits for
2507
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
2508
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2509
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2510
+ */
2511
+ await this.loadMarkets();
2512
+ let request = {
2513
+ // 'ccy': currency['id'],
2514
+ // 'state': 2, // 0 waiting for confirmation, 1 deposit credited, 2 deposit successful
2515
+ // 'after': since,
2516
+ // 'before' this.milliseconds (),
2517
+ // 'limit': limit, // default 100, max 100
2518
+ };
2519
+ let currency = undefined;
2520
+ if (code !== undefined) {
2521
+ currency = this.currency(code);
2522
+ request['ccy'] = currency['id'];
2523
+ }
2524
+ if (since !== undefined) {
2525
+ request['before'] = Math.max(since - 1, 0);
2526
+ }
2527
+ if (limit !== undefined) {
2528
+ request['limit'] = limit; // default 100, max 100
2529
+ }
2530
+ [request, params] = this.handleUntilOption('after', request, params);
2531
+ const response = await this.privateGetAssetDepositHistory(this.extend(request, params));
2532
+ //
2533
+ // {
2534
+ // "code": "0",
2535
+ // "msg": "",
2536
+ // "data": [
2537
+ // {
2538
+ // "amt": "0.01044408",
2539
+ // "txId": "1915737_3_0_0_asset",
2540
+ // "ccy": "BTC",
2541
+ // "from": "13801825426",
2542
+ // "to": "",
2543
+ // "ts": "1597026383085",
2544
+ // "state": "2",
2545
+ // "depId": "4703879"
2546
+ // },
2547
+ // {
2548
+ // "amt": "491.6784211",
2549
+ // "txId": "1744594_3_184_0_asset",
2550
+ // "ccy": "OKB",
2551
+ // "from": "",
2552
+ // "to": "",
2553
+ // "ts": "1597026383085",
2554
+ // "state": "2",
2555
+ // "depId": "4703809"
2556
+ // },
2557
+ // {
2558
+ // "amt": "223.18782496",
2559
+ // "txId": "6d892c669225b1092c780bf0da0c6f912fc7dc8f6b8cc53b003288624c",
2560
+ // "ccy": "USDT",
2561
+ // "from": "",
2562
+ // "to": "39kK4XvgEuM7rX9frgyHoZkWqx4iKu1spD",
2563
+ // "ts": "1597026383085",
2564
+ // "state": "2",
2565
+ // "depId": "4703779"
2566
+ // }
2567
+ // ]
2568
+ // }
2569
+ //
2570
+ const data = this.safeValue(response, 'data', []);
2571
+ return this.parseTransactions(data, currency, since, limit, params);
2572
+ }
2573
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2574
+ /**
2575
+ * @method
2576
+ * @name okcoin#fetchWithdrawals
2577
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
2578
+ * @description fetch all withdrawals made from an account
2579
+ * @param {string} code unified currency code
2580
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
2581
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
2582
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2583
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2584
+ */
2585
+ await this.loadMarkets();
2586
+ let request = {
2587
+ // 'ccy': currency['id'],
2588
+ // 'state': 2, // -3: pending cancel, -2 canceled, -1 failed, 0, pending, 1 sending, 2 sent, 3 awaiting email verification, 4 awaiting manual verification, 5 awaiting identity verification
2589
+ // 'after': since,
2590
+ // 'before': this.milliseconds (),
2591
+ // 'limit': limit, // default 100, max 100
2592
+ };
2593
+ let currency = undefined;
2594
+ if (code !== undefined) {
2595
+ currency = this.currency(code);
2596
+ request['ccy'] = currency['id'];
2597
+ }
2598
+ if (since !== undefined) {
2599
+ request['before'] = Math.max(since - 1, 0);
2600
+ }
2601
+ if (limit !== undefined) {
2602
+ request['limit'] = limit; // default 100, max 100
2603
+ }
2604
+ [request, params] = this.handleUntilOption('after', request, params);
2605
+ const response = await this.privateGetAssetWithdrawalHistory(this.extend(request, params));
2606
+ //
2607
+ // {
2608
+ // "code": "0",
2609
+ // "msg": "",
2610
+ // "data": [
2611
+ // {
2612
+ // "amt": "0.094",
2613
+ // "wdId": "4703879",
2614
+ // "fee": "0.01000000eth",
2615
+ // "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85",
2616
+ // "ccy": "ETH",
2617
+ // "from": "13426335357",
2618
+ // "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519",
2619
+ // "ts": "1597026383085",
2620
+ // "state": "2"
2621
+ // },
2622
+ // {
2623
+ // "amt": "0.01",
2624
+ // "wdId": "4703879",
2625
+ // "fee": "0.00000000btc",
2626
+ // "txId": "",
2627
+ // "ccy": "BTC",
2628
+ // "from": "13426335357",
2629
+ // "to": "13426335357",
2630
+ // "ts": "1597026383085",
2631
+ // "state": "2"
2632
+ // }
2633
+ // ]
2634
+ // }
2635
+ //
2636
+ const data = this.safeValue(response, 'data', []);
2637
+ return this.parseTransactions(data, currency, since, limit, params);
2638
+ }
2639
+ parseTransactionStatus(status) {
2640
+ //
2641
+ // deposit statuses
2642
+ //
2643
+ // {
2644
+ // "0": "waiting for confirmation",
2645
+ // "1": "confirmation account",
2646
+ // "2": "recharge success"
2647
+ // }
2648
+ //
2649
+ // withdrawal statues
2650
+ //
2651
+ // {
2652
+ // '-3': "pending cancel",
2653
+ // "-2": "cancelled",
2654
+ // "-1": "failed",
2655
+ // "0": "pending",
2656
+ // "1": "sending",
2657
+ // "2": "sent",
2658
+ // "3": "email confirmation",
2659
+ // "4": "manual confirmation",
2660
+ // "5": "awaiting identity confirmation"
2661
+ // }
2662
+ //
2663
+ const statuses = {
2664
+ '-3': 'pending',
2665
+ '-2': 'canceled',
2666
+ '-1': 'failed',
2667
+ '0': 'pending',
2668
+ '1': 'pending',
2669
+ '2': 'ok',
2670
+ '3': 'pending',
2671
+ '4': 'pending',
2672
+ '5': 'pending',
2673
+ };
2674
+ return this.safeString(statuses, status, status);
2675
+ }
2676
+ parseTransaction(transaction, currency = undefined) {
2677
+ //
2678
+ // withdraw
2679
+ //
2680
+ // {
2681
+ // "amt": "0.1",
2682
+ // "wdId": "67485",
2683
+ // "ccy": "BTC"
2684
+ // }
2685
+ //
2686
+ // fetchWithdrawals
2687
+ //
2688
+ // {
2689
+ // "amt": "0.094",
2690
+ // "wdId": "4703879",
2691
+ // "fee": "0.01000000eth",
2692
+ // "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85",
2693
+ // "ccy": "ETH",
2694
+ // "from": "13426335357",
2695
+ // "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519",
2696
+ // "tag",
2697
+ // "pmtId",
2698
+ // "memo",
2699
+ // "ts": "1597026383085",
2700
+ // "state": "2"
2701
+ // }
2702
+ //
2703
+ // fetchDeposits
2704
+ //
2705
+ // {
2706
+ // "amt": "0.01044408",
2707
+ // "txId": "1915737_3_0_0_asset",
2708
+ // "ccy": "BTC",
2709
+ // "from": "13801825426",
2710
+ // "to": "",
2711
+ // "ts": "1597026383085",
2712
+ // "state": "2",
2713
+ // "depId": "4703879"
2714
+ // }
2715
+ //
2716
+ let type = undefined;
2717
+ let id = undefined;
2718
+ const withdrawalId = this.safeString(transaction, 'wdId');
2719
+ const addressFrom = this.safeString(transaction, 'from');
2720
+ const addressTo = this.safeString(transaction, 'to');
2721
+ const address = addressTo;
2722
+ let tagTo = this.safeString2(transaction, 'tag', 'memo');
2723
+ tagTo = this.safeString2(transaction, 'pmtId', tagTo);
2724
+ if (withdrawalId !== undefined) {
2725
+ type = 'withdrawal';
2726
+ id = withdrawalId;
2727
+ }
2728
+ else {
2729
+ // the payment_id will appear on new deposits but appears to be removed from the response after 2 months
2730
+ id = this.safeString(transaction, 'depId');
2731
+ type = 'deposit';
2732
+ }
2733
+ const currencyId = this.safeString(transaction, 'ccy');
2734
+ const code = this.safeCurrencyCode(currencyId);
2735
+ const amount = this.safeNumber(transaction, 'amt');
2736
+ const status = this.parseTransactionStatus(this.safeString(transaction, 'state'));
2737
+ const txid = this.safeString(transaction, 'txId');
2738
+ const timestamp = this.safeInteger(transaction, 'ts');
2739
+ let feeCost = undefined;
2740
+ if (type === 'deposit') {
2741
+ feeCost = 0;
2742
+ }
2743
+ else {
2744
+ feeCost = this.safeNumber(transaction, 'fee');
2745
+ }
2746
+ // todo parse tags
2747
+ return {
2748
+ 'info': transaction,
2749
+ 'id': id,
2750
+ 'currency': code,
2751
+ 'amount': amount,
2752
+ 'network': undefined,
2753
+ 'addressFrom': addressFrom,
2754
+ 'addressTo': addressTo,
2755
+ 'address': address,
2756
+ 'tagFrom': undefined,
2757
+ 'tagTo': tagTo,
2758
+ 'tag': tagTo,
2759
+ 'status': status,
2760
+ 'type': type,
2761
+ 'updated': undefined,
2762
+ 'txid': txid,
2763
+ 'timestamp': timestamp,
2764
+ 'datetime': this.iso8601(timestamp),
2765
+ 'comment': undefined,
2766
+ 'internal': undefined,
2767
+ 'fee': {
2768
+ 'currency': code,
2769
+ 'cost': feeCost,
2770
+ },
2771
+ };
2772
+ }
2773
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2774
+ /**
2775
+ * @method
2776
+ * @name okcoin#fetchMyTrades
2777
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-days
2778
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-months
2779
+ * @description fetch all trades made by the user
2780
+ * @param {string} symbol unified market symbol
2781
+ * @param {int} [since] the earliest time in ms to fetch trades for
2782
+ * @param {int} [limit] the maximum number of trades structures to retrieve
2783
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2784
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
2785
+ */
2786
+ await this.loadMarkets();
2787
+ const request = {
2788
+ 'instType': 'SPOT',
2789
+ };
2790
+ if ((limit !== undefined) && (limit > 100)) {
2791
+ limit = 100;
2792
+ }
2793
+ let market = undefined;
2794
+ if (symbol !== undefined) {
2795
+ market = this.market(symbol);
2796
+ request['instId'] = market['id'];
2797
+ }
2798
+ let method = undefined;
2799
+ [method, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'method', 'privateGetTradeFillsHistory');
2800
+ let response = undefined;
2801
+ if (method === 'privateGetTradeFillsHistory') {
2802
+ response = await this.privateGetTradeFillsHistory(this.extend(request, params));
2803
+ }
2804
+ else {
2805
+ response = await this.privateGetTradeFills(this.extend(request, params));
2806
+ }
2807
+ const data = this.safeValue(response, 'data', []);
2808
+ return this.parseTrades(data, market, since, limit);
2809
+ }
2810
+ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
2811
+ /**
2812
+ * @method
2813
+ * @name okcoin#fetchOrderTrades
2814
+ * @description fetch all the trades made from a single order
2815
+ * @param {string} id order id
2816
+ * @param {string} symbol unified market symbol
2817
+ * @param {int} [since] the earliest time in ms to fetch trades for
2818
+ * @param {int} [limit] the maximum number of trades to retrieve
2819
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2820
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
2821
+ */
2822
+ const request = {
2823
+ // 'instrument_id': market['id'],
2824
+ 'order_id': id,
2825
+ // 'after': '1', // return the page after the specified page number
2826
+ // 'before': '1', // return the page before the specified page number
2827
+ // 'limit': limit, // optional, number of results per request, default = maximum = 100
2828
+ };
2829
+ return await this.fetchMyTrades(symbol, since, limit, this.extend(request, params));
2830
+ }
2831
+ async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
2832
+ /**
2833
+ * @method
2834
+ * @name okcoin#fetchLedger
2835
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-funding-asset-bills-details
2836
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
2837
+ * @see https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
2838
+ * @description fetch the history of changes, actions done by the user or operations that altered balance of the user
2839
+ * @param {string} code unified currency code, default is undefined
2840
+ * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
2841
+ * @param {int} [limit] max number of ledger entrys to return, default is undefined
2842
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2843
+ * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
2844
+ */
2845
+ await this.loadMarkets();
2846
+ let method = undefined;
2847
+ [method, params] = this.handleOptionAndParams(params, 'fetchLedger', 'method', 'privateGetAccountBills');
2848
+ let request = {
2849
+ // 'instType': undefined, // 'SPOT', 'MARGIN', 'SWAP', 'FUTURES", 'OPTION'
2850
+ // 'ccy': undefined, // currency['id'],
2851
+ // 'ctType': undefined, // 'linear', 'inverse', only applicable to FUTURES/SWAP
2852
+ // 'type': varies depending the 'method' endpoint :
2853
+ // - https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
2854
+ // - https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
2855
+ // - https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
2856
+ // 'after': 'id', // return records earlier than the requested bill id
2857
+ // 'before': 'id', // return records newer than the requested bill id
2858
+ // 'limit': 100, // default 100, max 100
2859
+ };
2860
+ if (limit !== undefined) {
2861
+ request['limit'] = limit;
2862
+ }
2863
+ let currency = undefined;
2864
+ if (code !== undefined) {
2865
+ currency = this.currency(code);
2866
+ request['ccy'] = currency['id'];
2867
+ }
2868
+ [request, params] = this.handleUntilOption('end', request, params);
2869
+ let response = undefined;
2870
+ if (method === 'privateGetAccountBillsArchive') {
2871
+ response = await this.privateGetAccountBillsArchive(this.extend(request, params));
2872
+ }
2873
+ else if (method === 'privateGetAssetBills') {
2874
+ response = await this.privateGetAssetBills(this.extend(request, params));
2875
+ }
2876
+ else {
2877
+ response = await this.privateGetAccountBills(this.extend(request, params));
2878
+ }
2879
+ //
2880
+ // privateGetAccountBills, privateGetAccountBillsArchive
2881
+ //
2882
+ // {
2883
+ // "code": "0",
2884
+ // "msg": "",
2885
+ // "data": [
2886
+ // {
2887
+ // "bal": "0.0000819307998198",
2888
+ // "balChg": "-664.2679586599999802",
2889
+ // "billId": "310394313544966151",
2890
+ // "ccy": "USDT",
2891
+ // "fee": "0",
2892
+ // "from": "",
2893
+ // "instId": "LTC-USDT",
2894
+ // "instType": "SPOT",
2895
+ // "mgnMode": "cross",
2896
+ // "notes": "",
2897
+ // "ordId": "310394313519800320",
2898
+ // "pnl": "0",
2899
+ // "posBal": "0",
2900
+ // "posBalChg": "0",
2901
+ // "subType": "2",
2902
+ // "sz": "664.26795866",
2903
+ // "to": "",
2904
+ // "ts": "1620275771196",
2905
+ // "type": "2"
2906
+ // }
2907
+ // ]
2908
+ // }
2909
+ //
2910
+ // privateGetAssetBills
2911
+ //
2912
+ // {
2913
+ // "code": "0",
2914
+ // "msg": "",
2915
+ // "data": [
2916
+ // {
2917
+ // "billId": "12344",
2918
+ // "ccy": "BTC",
2919
+ // "balChg": "2",
2920
+ // "bal": "12",
2921
+ // "type": "1",
2922
+ // "ts": "1597026383085"
2923
+ // }
2924
+ // ]
2925
+ // }
2926
+ //
2927
+ const data = this.safeValue(response, 'data', []);
2928
+ return this.parseLedger(data, currency, since, limit);
2929
+ }
2930
+ parseLedgerEntryType(type) {
2931
+ const types = {
2932
+ '1': 'transfer',
2933
+ '2': 'trade',
2934
+ '3': 'trade',
2935
+ '4': 'rebate',
2936
+ '5': 'trade',
2937
+ '6': 'transfer',
2938
+ '7': 'trade',
2939
+ '8': 'fee',
2940
+ '9': 'trade',
2941
+ '10': 'trade',
2942
+ '11': 'trade', // system token conversion
2943
+ };
2944
+ return this.safeString(types, type, type);
2945
+ }
2946
+ parseLedgerEntry(item, currency = undefined) {
2947
+ //
2948
+ // privateGetAccountBills, privateGetAccountBillsArchive
2949
+ //
2950
+ // {
2951
+ // "bal": "0.0000819307998198",
2952
+ // "balChg": "-664.2679586599999802",
2953
+ // "billId": "310394313544966151",
2954
+ // "ccy": "USDT",
2955
+ // "fee": "0",
2956
+ // "from": "",
2957
+ // "instId": "LTC-USDT",
2958
+ // "instType": "SPOT",
2959
+ // "mgnMode": "cross",
2960
+ // "notes": "",
2961
+ // "ordId": "310394313519800320",
2962
+ // "pnl": "0",
2963
+ // "posBal": "0",
2964
+ // "posBalChg": "0",
2965
+ // "subType": "2",
2966
+ // "sz": "664.26795866",
2967
+ // "to": "",
2968
+ // "ts": "1620275771196",
2969
+ // "type": "2"
2970
+ // }
2971
+ //
2972
+ // privateGetAssetBills
2973
+ //
2974
+ // {
2975
+ // "billId": "12344",
2976
+ // "ccy": "BTC",
2977
+ // "balChg": "2",
2978
+ // "bal": "12",
2979
+ // "type": "1",
2980
+ // "ts": "1597026383085"
2981
+ // }
2982
+ //
2983
+ const id = this.safeString(item, 'billId');
2984
+ const account = undefined;
2985
+ const referenceId = this.safeString(item, 'ordId');
2986
+ const referenceAccount = undefined;
2987
+ const type = this.parseLedgerEntryType(this.safeString(item, 'type'));
2988
+ const code = this.safeCurrencyCode(this.safeString(item, 'ccy'), currency);
2989
+ const amountString = this.safeString(item, 'balChg');
2990
+ const amount = this.parseNumber(amountString);
2991
+ const timestamp = this.safeInteger(item, 'ts');
2992
+ const feeCostString = this.safeString(item, 'fee');
2993
+ let fee = undefined;
2994
+ if (feeCostString !== undefined) {
2995
+ fee = {
2996
+ 'cost': this.parseNumber(Precise["default"].stringNeg(feeCostString)),
2997
+ 'currency': code,
2998
+ };
2999
+ }
3000
+ const before = undefined;
3001
+ const afterString = this.safeString(item, 'bal');
3002
+ const after = this.parseNumber(afterString);
3003
+ const status = 'ok';
3004
+ const marketId = this.safeString(item, 'instId');
3005
+ const symbol = this.safeSymbol(marketId, undefined, '-');
3006
+ return {
3007
+ 'id': id,
3008
+ 'info': item,
3009
+ 'timestamp': timestamp,
3010
+ 'datetime': this.iso8601(timestamp),
3011
+ 'account': account,
3012
+ 'referenceId': referenceId,
3013
+ 'referenceAccount': referenceAccount,
3014
+ 'type': type,
3015
+ 'currency': code,
3016
+ 'symbol': symbol,
3017
+ 'amount': amount,
3018
+ 'before': before,
3019
+ 'after': after,
3020
+ 'status': status,
3021
+ 'fee': fee,
3022
+ };
3023
+ }
3024
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3025
+ const isArray = Array.isArray(params);
3026
+ const request = '/api/' + this.version + '/' + this.implodeParams(path, params);
3027
+ const query = this.omit(params, this.extractParams(path));
3028
+ let url = this.implodeHostname(this.urls['api']['rest']) + request;
3029
+ if (api === 'public') {
3030
+ if (Object.keys(query).length) {
3031
+ url += '?' + this.urlencode(query);
3032
+ }
3033
+ }
3034
+ else if (api === 'private') {
3035
+ this.checkRequiredCredentials();
3036
+ const timestamp = this.iso8601(this.milliseconds());
3037
+ headers = {
3038
+ 'OK-ACCESS-KEY': this.apiKey,
3039
+ 'OK-ACCESS-PASSPHRASE': this.password,
3040
+ 'OK-ACCESS-TIMESTAMP': timestamp,
3041
+ // 'OK-FROM': '',
3042
+ // 'OK-TO': '',
3043
+ // 'OK-LIMIT': '',
3044
+ };
3045
+ let auth = timestamp + method + request;
3046
+ if (method === 'GET') {
3047
+ if (Object.keys(query).length) {
3048
+ const urlencodedQuery = '?' + this.urlencode(query);
3049
+ url += urlencodedQuery;
3050
+ auth += urlencodedQuery;
3051
+ }
3052
+ }
3053
+ else {
3054
+ if (isArray || Object.keys(query).length) {
3055
+ body = this.json(query);
3056
+ auth += body;
3057
+ }
3058
+ headers['Content-Type'] = 'application/json';
3059
+ }
3060
+ const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256, 'base64');
3061
+ headers['OK-ACCESS-SIGN'] = signature;
3062
+ }
3063
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3064
+ }
3065
+ parseBalanceByType(type, response) {
3066
+ if (type === 'funding') {
3067
+ return this.parseFundingBalance(response);
3068
+ }
3069
+ else {
3070
+ return this.parseTradingBalance(response);
3071
+ }
3072
+ }
3073
+ handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3074
+ if (!response) {
3075
+ return undefined; // fallback to default error handler
3076
+ }
3077
+ //
3078
+ // {
3079
+ // "code": "1",
3080
+ // "data": [
3081
+ // {
3082
+ // "clOrdId": "",
3083
+ // "ordId": "",
3084
+ // "sCode": "51119",
3085
+ // "sMsg": "Order placement failed due to insufficient balance. ",
3086
+ // "tag": ""
3087
+ // }
3088
+ // ],
3089
+ // "msg": ""
3090
+ // },
3091
+ // {
3092
+ // "code": "58001",
3093
+ // "data": [],
3094
+ // "msg": "Incorrect trade password"
3095
+ // }
3096
+ //
3097
+ const code = this.safeString(response, 'code');
3098
+ if (code !== '0') {
3099
+ const feedback = this.id + ' ' + body;
3100
+ const data = this.safeValue(response, 'data', []);
3101
+ for (let i = 0; i < data.length; i++) {
3102
+ const error = data[i];
3103
+ const errorCode = this.safeString(error, 'sCode');
3104
+ const message = this.safeString(error, 'sMsg');
3105
+ this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
3106
+ this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
3107
+ }
3108
+ this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
3109
+ throw new errors.ExchangeError(feedback); // unknown message
3110
+ }
3111
+ return undefined;
3112
+ }
3113
+ }
3114
+
3115
+ module.exports = okcoin;