ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +24 -0
  44. ccxt/abstract/kucoinfutures.py +34 -0
  45. ccxt/abstract/luno.py +2 -0
  46. ccxt/abstract/mexc.py +4 -0
  47. ccxt/abstract/myokx.py +340 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +30 -0
  50. ccxt/abstract/onetrading.py +0 -12
  51. ccxt/abstract/oxfun.py +34 -0
  52. ccxt/abstract/paradex.py +40 -0
  53. ccxt/abstract/phemex.py +1 -0
  54. ccxt/abstract/upbit.py +4 -0
  55. ccxt/abstract/vertex.py +19 -0
  56. ccxt/abstract/whitebit.py +31 -1
  57. ccxt/abstract/woo.py +6 -2
  58. ccxt/abstract/woofipro.py +119 -0
  59. ccxt/abstract/xt.py +153 -0
  60. ccxt/abstract/zonda.py +6 -0
  61. ccxt/ace.py +164 -60
  62. ccxt/alpaca.py +727 -63
  63. ccxt/ascendex.py +395 -249
  64. ccxt/async_support/__init__.py +36 -14
  65. ccxt/async_support/ace.py +164 -60
  66. ccxt/async_support/alpaca.py +727 -63
  67. ccxt/async_support/ascendex.py +396 -249
  68. ccxt/async_support/base/exchange.py +531 -155
  69. ccxt/async_support/base/ws/aiohttp_client.py +28 -5
  70. ccxt/async_support/base/ws/cache.py +3 -2
  71. ccxt/async_support/base/ws/client.py +26 -5
  72. ccxt/async_support/base/ws/fast_client.py +4 -3
  73. ccxt/async_support/base/ws/functions.py +1 -1
  74. ccxt/async_support/base/ws/future.py +40 -31
  75. ccxt/async_support/base/ws/order_book_side.py +3 -0
  76. ccxt/async_support/bequant.py +1 -1
  77. ccxt/async_support/bigone.py +329 -202
  78. ccxt/async_support/binance.py +3030 -1087
  79. ccxt/async_support/binancecoinm.py +2 -1
  80. ccxt/async_support/binanceus.py +12 -1
  81. ccxt/async_support/binanceusdm.py +3 -1
  82. ccxt/async_support/bingx.py +3104 -880
  83. ccxt/async_support/bit2c.py +119 -38
  84. ccxt/async_support/bitbank.py +215 -76
  85. ccxt/async_support/bitbns.py +124 -53
  86. ccxt/async_support/bitfinex.py +3236 -1078
  87. ccxt/async_support/bitfinex1.py +1711 -0
  88. ccxt/async_support/bitflyer.py +238 -49
  89. ccxt/async_support/bitget.py +1513 -563
  90. ccxt/async_support/bithumb.py +199 -65
  91. ccxt/async_support/bitmart.py +1320 -435
  92. ccxt/async_support/bitmex.py +308 -111
  93. ccxt/async_support/bitopro.py +256 -96
  94. ccxt/async_support/bitrue.py +365 -233
  95. ccxt/async_support/bitso.py +201 -89
  96. ccxt/async_support/bitstamp.py +438 -269
  97. ccxt/async_support/bitteam.py +179 -73
  98. ccxt/async_support/bitvavo.py +180 -70
  99. ccxt/async_support/bl3p.py +92 -25
  100. ccxt/async_support/blockchaincom.py +193 -79
  101. ccxt/async_support/blofin.py +392 -148
  102. ccxt/async_support/btcalpha.py +161 -55
  103. ccxt/async_support/btcbox.py +250 -34
  104. ccxt/async_support/btcmarkets.py +232 -85
  105. ccxt/async_support/btcturk.py +159 -60
  106. ccxt/async_support/bybit.py +2231 -1193
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1454 -287
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +206 -89
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +404 -109
  125. ccxt/async_support/deribit.py +557 -323
  126. ccxt/async_support/digifinex.py +340 -223
  127. ccxt/async_support/ellipx.py +1826 -0
  128. ccxt/async_support/exmo.py +259 -128
  129. ccxt/async_support/gate.py +1472 -463
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +334 -178
  133. ccxt/async_support/hollaex.py +134 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +105 -56
  136. ccxt/async_support/hyperliquid.py +1633 -268
  137. ccxt/async_support/idex.py +148 -95
  138. ccxt/async_support/independentreserve.py +236 -31
  139. ccxt/async_support/indodax.py +165 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +917 -357
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +138 -106
  145. ccxt/async_support/latoken.py +135 -79
  146. ccxt/async_support/lbank.py +290 -113
  147. ccxt/async_support/luno.py +112 -62
  148. ccxt/async_support/lykke.py +104 -55
  149. ccxt/async_support/mercado.py +36 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +43 -0
  152. ccxt/async_support/ndax.py +163 -82
  153. ccxt/async_support/novadax.py +121 -75
  154. ccxt/async_support/oceanex.py +175 -59
  155. ccxt/async_support/okcoin.py +222 -163
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +132 -414
  158. ccxt/async_support/oxfun.py +2832 -0
  159. ccxt/async_support/p2b.py +79 -51
  160. ccxt/async_support/paradex.py +2017 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1137 -296
  175. ccxt/async_support/woofipro.py +2716 -0
  176. ccxt/async_support/xt.py +4628 -0
  177. ccxt/async_support/yobit.py +160 -92
  178. ccxt/async_support/zaif.py +80 -33
  179. ccxt/async_support/zonda.py +140 -69
  180. ccxt/base/errors.py +51 -20
  181. ccxt/base/exchange.py +1722 -480
  182. ccxt/base/precise.py +10 -0
  183. ccxt/base/types.py +223 -4
  184. ccxt/bequant.py +1 -1
  185. ccxt/bigone.py +329 -202
  186. ccxt/binance.py +3030 -1087
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3104 -880
  191. ccxt/bit2c.py +119 -38
  192. ccxt/bitbank.py +215 -76
  193. ccxt/bitbns.py +124 -53
  194. ccxt/bitfinex.py +3235 -1078
  195. ccxt/bitfinex1.py +1710 -0
  196. ccxt/bitflyer.py +238 -49
  197. ccxt/bitget.py +1513 -563
  198. ccxt/bithumb.py +198 -65
  199. ccxt/bitmart.py +1320 -435
  200. ccxt/bitmex.py +308 -111
  201. ccxt/bitopro.py +256 -96
  202. ccxt/bitrue.py +365 -233
  203. ccxt/bitso.py +201 -89
  204. ccxt/bitstamp.py +438 -269
  205. ccxt/bitteam.py +179 -73
  206. ccxt/bitvavo.py +180 -70
  207. ccxt/bl3p.py +92 -25
  208. ccxt/blockchaincom.py +193 -79
  209. ccxt/blofin.py +392 -148
  210. ccxt/btcalpha.py +161 -55
  211. ccxt/btcbox.py +250 -34
  212. ccxt/btcmarkets.py +232 -85
  213. ccxt/btcturk.py +159 -60
  214. ccxt/bybit.py +2231 -1193
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1454 -287
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +206 -89
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +404 -109
  233. ccxt/deribit.py +557 -323
  234. ccxt/digifinex.py +340 -223
  235. ccxt/ellipx.py +1826 -0
  236. ccxt/exmo.py +259 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +334 -178
  241. ccxt/hollaex.py +134 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +105 -56
  244. ccxt/hyperliquid.py +1632 -268
  245. ccxt/idex.py +148 -95
  246. ccxt/independentreserve.py +235 -31
  247. ccxt/indodax.py +165 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +917 -357
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +138 -106
  253. ccxt/latoken.py +135 -79
  254. ccxt/lbank.py +290 -113
  255. ccxt/luno.py +112 -62
  256. ccxt/lykke.py +104 -55
  257. ccxt/mercado.py +36 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +43 -0
  260. ccxt/ndax.py +163 -82
  261. ccxt/novadax.py +121 -75
  262. ccxt/oceanex.py +175 -59
  263. ccxt/okcoin.py +222 -163
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +132 -414
  266. ccxt/oxfun.py +2831 -0
  267. ccxt/p2b.py +79 -51
  268. ccxt/paradex.py +2017 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +62 -14
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +138 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +203 -81
  293. ccxt/pro/blockchaincom.py +30 -17
  294. ccxt/pro/blofin.py +692 -0
  295. ccxt/pro/bybit.py +791 -82
  296. ccxt/pro/cex.py +99 -51
  297. ccxt/pro/coinbase.py +220 -30
  298. ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
  299. ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
  300. ccxt/pro/coinbaseinternational.py +193 -30
  301. ccxt/pro/coincatch.py +1464 -0
  302. ccxt/pro/coincheck.py +11 -6
  303. ccxt/pro/coinex.py +965 -665
  304. ccxt/pro/coinone.py +17 -10
  305. ccxt/pro/cryptocom.py +446 -66
  306. ccxt/pro/currencycom.py +11 -10
  307. ccxt/pro/defx.py +832 -0
  308. ccxt/pro/deribit.py +167 -31
  309. ccxt/pro/exmo.py +252 -20
  310. ccxt/pro/gate.py +729 -64
  311. ccxt/pro/gemini.py +44 -26
  312. ccxt/pro/hashkey.py +802 -0
  313. ccxt/pro/hitbtc.py +208 -103
  314. ccxt/pro/hollaex.py +25 -9
  315. ccxt/pro/htx.py +83 -39
  316. ccxt/pro/huobijp.py +17 -16
  317. ccxt/pro/hyperliquid.py +502 -31
  318. ccxt/pro/idex.py +28 -13
  319. ccxt/pro/independentreserve.py +21 -16
  320. ccxt/pro/kraken.py +298 -51
  321. ccxt/pro/krakenfutures.py +166 -75
  322. ccxt/pro/kucoin.py +395 -77
  323. ccxt/pro/kucoinfutures.py +400 -99
  324. ccxt/pro/lbank.py +52 -31
  325. ccxt/pro/luno.py +12 -10
  326. ccxt/pro/mexc.py +400 -50
  327. ccxt/pro/myokx.py +28 -0
  328. ccxt/pro/ndax.py +25 -12
  329. ccxt/pro/okcoin.py +28 -9
  330. ccxt/pro/okx.py +935 -124
  331. ccxt/pro/onetrading.py +41 -24
  332. ccxt/pro/oxfun.py +1054 -0
  333. ccxt/pro/p2b.py +100 -24
  334. ccxt/pro/paradex.py +352 -0
  335. ccxt/pro/phemex.py +92 -33
  336. ccxt/pro/poloniex.py +128 -49
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +92 -85
  339. ccxt/pro/upbit.py +401 -8
  340. ccxt/pro/vertex.py +943 -0
  341. ccxt/pro/wazirx.py +46 -28
  342. ccxt/pro/whitebit.py +65 -12
  343. ccxt/pro/woo.py +437 -65
  344. ccxt/pro/woofipro.py +1271 -0
  345. ccxt/pro/xt.py +1067 -0
  346. ccxt/probit.py +143 -110
  347. ccxt/static_dependencies/__init__.py +1 -1
  348. ccxt/static_dependencies/lark/__init__.py +38 -0
  349. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  350. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  351. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  352. ccxt/static_dependencies/lark/common.py +86 -0
  353. ccxt/static_dependencies/lark/exceptions.py +292 -0
  354. ccxt/static_dependencies/lark/grammar.py +130 -0
  355. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  356. ccxt/static_dependencies/lark/indenter.py +143 -0
  357. ccxt/static_dependencies/lark/lark.py +658 -0
  358. ccxt/static_dependencies/lark/lexer.py +678 -0
  359. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  360. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  361. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  362. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  363. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  364. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  365. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  366. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  367. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  368. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  369. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  370. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  371. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  372. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  373. ccxt/static_dependencies/lark/py.typed +0 -0
  374. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  375. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  376. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  377. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  378. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  379. ccxt/static_dependencies/lark/tree.py +267 -0
  380. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  381. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  382. ccxt/static_dependencies/lark/utils.py +343 -0
  383. ccxt/static_dependencies/lark/visitors.py +596 -0
  384. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  385. ccxt/static_dependencies/marshmallow/base.py +65 -0
  386. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  387. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  388. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  389. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  390. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  391. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  392. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  393. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  394. ccxt/static_dependencies/marshmallow/types.py +12 -0
  395. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  396. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  397. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  398. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  399. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  400. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  401. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  402. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  403. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  404. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  405. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  406. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  407. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  408. ccxt/static_dependencies/starknet/__init__.py +0 -0
  409. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  410. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  411. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  412. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  413. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  414. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  415. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  416. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  417. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  418. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  419. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  420. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  421. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  422. ccxt/static_dependencies/starknet/common.py +15 -0
  423. ccxt/static_dependencies/starknet/constants.py +39 -0
  424. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  425. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  426. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  427. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  428. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  429. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  430. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  431. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  432. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  433. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  434. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  435. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  436. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  437. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  438. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  439. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  440. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  441. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  442. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  443. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  444. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  445. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  446. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  447. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  448. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  449. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  450. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  451. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  452. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  453. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  454. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  455. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  456. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  457. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  458. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  459. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  460. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  461. ccxt/static_dependencies/starkware/__init__.py +0 -0
  462. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  463. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  464. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  465. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  466. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  467. ccxt/static_dependencies/sympy/__init__.py +0 -0
  468. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  469. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  470. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  471. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  472. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  473. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  474. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  475. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  476. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  477. ccxt/test/{test_async.py → tests_async.py} +456 -391
  478. ccxt/test/tests_helpers.py +285 -0
  479. ccxt/test/tests_init.py +39 -0
  480. ccxt/test/{test_sync.py → tests_sync.py} +456 -393
  481. ccxt/timex.py +123 -70
  482. ccxt/tokocrypto.py +129 -93
  483. ccxt/tradeogre.py +39 -25
  484. ccxt/upbit.py +322 -113
  485. ccxt/vertex.py +2983 -0
  486. ccxt/wavesexchange.py +227 -173
  487. ccxt/wazirx.py +145 -65
  488. ccxt/whitebit.py +533 -138
  489. ccxt/woo.py +1137 -296
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.48.dist-info/METADATA +646 -0
  497. ccxt-4.4.48.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.77.dist-info/METADATA +0 -626
  545. ccxt-4.2.77.dist-info/RECORD +0 -534
  546. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/async_support/htx.py CHANGED
@@ -7,9 +7,10 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.htx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, BorrowInterest, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
13
14
  from ccxt.base.errors import PermissionDenied
14
15
  from ccxt.base.errors import AccountNotEnabled
15
16
  from ccxt.base.errors import ArgumentsRequired
@@ -19,12 +20,11 @@ from ccxt.base.errors import InsufficientFunds
19
20
  from ccxt.base.errors import InvalidOrder
20
21
  from ccxt.base.errors import OrderNotFound
21
22
  from ccxt.base.errors import NotSupported
22
- from ccxt.base.errors import NetworkError
23
+ from ccxt.base.errors import OperationFailed
23
24
  from ccxt.base.errors import RateLimitExceeded
24
25
  from ccxt.base.errors import ExchangeNotAvailable
25
26
  from ccxt.base.errors import OnMaintenance
26
27
  from ccxt.base.errors import RequestTimeout
27
- from ccxt.base.errors import AuthenticationError
28
28
  from ccxt.base.decimal_to_precision import TRUNCATE
29
29
  from ccxt.base.decimal_to_precision import TICK_SIZE
30
30
  from ccxt.base.precise import Precise
@@ -54,8 +54,11 @@ class htx(Exchange, ImplicitAPI):
54
54
  'borrowCrossMargin': True,
55
55
  'borrowIsolatedMargin': True,
56
56
  'cancelAllOrders': True,
57
+ 'cancelAllOrdersAfter': True,
57
58
  'cancelOrder': True,
58
59
  'cancelOrders': True,
60
+ 'closeAllPositions': False,
61
+ 'closePosition': True,
59
62
  'createDepositAddress': None,
60
63
  'createMarketBuyOrderWithCost': True,
61
64
  'createMarketOrderWithCost': False,
@@ -103,7 +106,8 @@ class htx(Exchange, ImplicitAPI):
103
106
  'fetchLeverage': False,
104
107
  'fetchLeverageTiers': True,
105
108
  'fetchLiquidations': True,
106
- 'fetchMarketLeverageTiers': True,
109
+ 'fetchMarginAdjustmentHistory': False,
110
+ 'fetchMarketLeverageTiers': 'emulated',
107
111
  'fetchMarkets': True,
108
112
  'fetchMarkOHLCV': True,
109
113
  'fetchMyLiquidations': False,
@@ -111,6 +115,7 @@ class htx(Exchange, ImplicitAPI):
111
115
  'fetchOHLCV': True,
112
116
  'fetchOpenInterest': True,
113
117
  'fetchOpenInterestHistory': True,
118
+ 'fetchOpenInterests': True,
114
119
  'fetchOpenOrder': None,
115
120
  'fetchOpenOrders': True,
116
121
  'fetchOrder': True,
@@ -119,7 +124,9 @@ class htx(Exchange, ImplicitAPI):
119
124
  'fetchOrders': True,
120
125
  'fetchOrderTrades': True,
121
126
  'fetchPosition': True,
127
+ 'fetchPositionHistory': 'emulated',
122
128
  'fetchPositions': True,
129
+ 'fetchPositionsHistory': False,
123
130
  'fetchPositionsRisk': False,
124
131
  'fetchPremiumIndexOHLCV': True,
125
132
  'fetchSettlementHistory': True,
@@ -197,7 +204,7 @@ class htx(Exchange, ImplicitAPI):
197
204
  },
198
205
  'www': 'https://www.huobi.com',
199
206
  'referral': {
200
- 'url': 'https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=6rmm2223',
207
+ 'url': 'https://www.htx.com.vc/invite/en-us/1h?invite_code=6rmm2223',
201
208
  'discount': 0.15,
202
209
  },
203
210
  'doc': [
@@ -958,16 +965,12 @@ class htx(Exchange, ImplicitAPI):
958
965
  'fetchMarkets': {
959
966
  'types': {
960
967
  'spot': True,
961
- 'future': {
962
- 'linear': True,
963
- 'inverse': True,
964
- },
965
- 'swap': {
966
- 'linear': True,
967
- 'inverse': True,
968
- },
968
+ 'linear': True,
969
+ 'inverse': True,
969
970
  },
970
971
  },
972
+ 'timeDifference': 0, # the difference between system clock and exchange clock
973
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
971
974
  'fetchOHLCV': {
972
975
  'useHistoricalEndpointForSpot': True,
973
976
  },
@@ -1237,21 +1240,159 @@ class htx(Exchange, ImplicitAPI):
1237
1240
  # https://github.com/ccxt/ccxt/issues/6081
1238
1241
  # https://github.com/ccxt/ccxt/issues/3365
1239
1242
  # https://github.com/ccxt/ccxt/issues/2873
1240
- 'GET': 'Themis', # conflict with GET(Guaranteed Entrance Token, GET Protocol)
1241
- 'GTC': 'Game.com', # conflict with Gitcoin and Gastrocoin
1242
- 'HIT': 'HitChain',
1243
+ 'NGL': 'GFNGL',
1244
+ 'GET': 'THEMIS', # conflict with GET(Guaranteed Entrance Token, GET Protocol)
1245
+ 'GTC': 'GAMECOM', # conflict with Gitcoin and Gastrocoin
1246
+ 'HIT': 'HITCHAIN',
1243
1247
  # https://github.com/ccxt/ccxt/issues/7399
1244
1248
  # https://coinmarketcap.com/currencies/pnetwork/
1245
1249
  # https://coinmarketcap.com/currencies/penta/markets/
1246
1250
  # https://en.cryptonomist.ch/blog/eidoo/the-edo-to-pnt-upgrade-what-you-need-to-know-updated/
1247
- 'PNT': 'Penta',
1248
- 'SBTC': 'Super Bitcoin',
1249
- 'SOUL': 'Soulsaver',
1250
- 'BIFI': 'Bitcoin File', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
1251
+ 'PNT': 'PENTA',
1252
+ 'SBTC': 'SUPERBITCOIN',
1253
+ 'SOUL': 'SOULSAVER',
1254
+ 'BIFI': 'BITCOINFILE', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
1255
+ 'FUD': 'FTX Users Debt',
1256
+ },
1257
+ 'features': {
1258
+ 'spot': {
1259
+ 'sandbox': True,
1260
+ 'createOrder': {
1261
+ 'marginMode': True,
1262
+ 'triggerPrice': True,
1263
+ 'triggerDirection': True,
1264
+ 'triggerPriceType': None,
1265
+ 'stopLossPrice': False, # todo: add support by triggerprice
1266
+ 'takeProfitPrice': False,
1267
+ 'attachedStopLossTakeProfit': None,
1268
+ 'timeInForce': {
1269
+ 'IOC': True,
1270
+ 'FOK': True,
1271
+ 'PO': True,
1272
+ 'GTD': False,
1273
+ },
1274
+ 'hedged': False,
1275
+ 'trailing': False,
1276
+ 'iceberg': False,
1277
+ 'selfTradePrevention': True, # todo implement
1278
+ 'leverage': True, # todo implement
1279
+ 'marketBuyByCost': True,
1280
+ 'marketBuyRequiresPrice': True,
1281
+ },
1282
+ 'createOrders': {
1283
+ 'max': 10,
1284
+ },
1285
+ 'fetchMyTrades': {
1286
+ 'marginMode': False,
1287
+ 'limit': 500,
1288
+ 'daysBack': 120,
1289
+ 'untilDays': 2,
1290
+ },
1291
+ 'fetchOrder': {
1292
+ 'marginMode': False,
1293
+ 'trigger': False,
1294
+ 'trailing': False,
1295
+ },
1296
+ 'fetchOpenOrders': {
1297
+ 'marginMode': False,
1298
+ 'trigger': True,
1299
+ 'trailing': False,
1300
+ 'limit': 500,
1301
+ },
1302
+ 'fetchOrders': {
1303
+ 'marginMode': False,
1304
+ 'trigger': True,
1305
+ 'trailing': False,
1306
+ 'limit': 500,
1307
+ 'untilDays': 2,
1308
+ 'daysBack': 180,
1309
+ },
1310
+ 'fetchClosedOrders': {
1311
+ 'marginMode': False,
1312
+ 'trigger': True,
1313
+ 'trailing': False,
1314
+ 'untilDays': 2,
1315
+ 'limit': 500,
1316
+ 'daysBack': 180,
1317
+ 'daysBackCanceled': 1 / 12,
1318
+ },
1319
+ 'fetchOHLCV': {
1320
+ 'limit': 1000, # 2000 for non-historical
1321
+ },
1322
+ },
1323
+ 'forDerivatives': {
1324
+ 'extends': 'spot',
1325
+ 'createOrder': {
1326
+ 'stopLossPrice': True,
1327
+ 'takeProfitPrice': True,
1328
+ 'trailing': True,
1329
+ 'hedged': True,
1330
+ # 'leverage': True, # todo
1331
+ },
1332
+ 'createOrders': {
1333
+ 'max': 25,
1334
+ },
1335
+ 'fetchOrder': {
1336
+ 'marginMode': True,
1337
+ },
1338
+ 'fetchOpenOrders': {
1339
+ 'marginMode': True,
1340
+ 'trigger': False,
1341
+ 'trailing': False,
1342
+ 'limit': 50,
1343
+ },
1344
+ 'fetchOrders': {
1345
+ 'marginMode': True,
1346
+ 'trigger': False,
1347
+ 'trailing': False,
1348
+ 'limit': 50,
1349
+ 'daysBack': 90,
1350
+ },
1351
+ 'fetchClosedOrders': {
1352
+ 'marginMode': True,
1353
+ 'trigger': False,
1354
+ 'trailing': False,
1355
+ 'untilDays': 2,
1356
+ 'limit': 50,
1357
+ 'daysBack': 90,
1358
+ 'daysBackCanceled': 1 / 12,
1359
+ },
1360
+ 'fetchOHLCV': {
1361
+ 'limit': 2000,
1362
+ },
1363
+ },
1364
+ 'swap': {
1365
+ 'linear': {
1366
+ 'extends': 'forDerivatives',
1367
+ },
1368
+ 'inverse': {
1369
+ 'extends': 'forDerivatives',
1370
+ },
1371
+ },
1372
+ 'future': {
1373
+ 'linear': {
1374
+ 'extends': 'forDerivatives',
1375
+ },
1376
+ 'inverse': {
1377
+ 'extends': 'forDerivatives',
1378
+ },
1379
+ },
1251
1380
  },
1252
1381
  })
1253
1382
 
1254
1383
  async def fetch_status(self, params={}):
1384
+ """
1385
+ the latest known information on the availability of the exchange API
1386
+
1387
+ https://huobiapi.github.io/docs/spot/v1/en/#get-system-status
1388
+ https://huobiapi.github.io/docs/dm/v1/en/#get-system-status
1389
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-system-status
1390
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#get-system-status
1391
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#query-whether-the-system-is-available # contractPublicGetHeartbeat
1392
+
1393
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1394
+ :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
1395
+ """
1255
1396
  await self.load_markets()
1256
1397
  marketType = None
1257
1398
  marketType, params = self.handle_market_type_and_params('fetchStatus', None, params)
@@ -1463,6 +1604,10 @@ class htx(Exchange, ImplicitAPI):
1463
1604
  async def fetch_time(self, params={}):
1464
1605
  """
1465
1606
  fetches the current integer timestamp in milliseconds from the exchange server
1607
+
1608
+ https://huobiapi.github.io/docs/spot/v1/en/#get-current-timestamp
1609
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-current-system-timestamp
1610
+
1466
1611
  :param dict [params]: extra parameters specific to the exchange API endpoint
1467
1612
  :returns int: the current integer timestamp in milliseconds from the exchange server
1468
1613
  """
@@ -1486,7 +1631,7 @@ class htx(Exchange, ImplicitAPI):
1486
1631
  #
1487
1632
  return self.safe_integer_2(response, 'data', 'ts')
1488
1633
 
1489
- def parse_trading_fee(self, fee, market: Market = None):
1634
+ def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
1490
1635
  #
1491
1636
  # {
1492
1637
  # "symbol":"btcusdt",
@@ -1502,18 +1647,23 @@ class htx(Exchange, ImplicitAPI):
1502
1647
  'symbol': self.safe_symbol(marketId, market),
1503
1648
  'maker': self.safe_number(fee, 'actualMakerRate'),
1504
1649
  'taker': self.safe_number(fee, 'actualTakerRate'),
1650
+ 'percentage': None,
1651
+ 'tierBased': None,
1505
1652
  }
1506
1653
 
1507
- async def fetch_trading_fee(self, symbol: str, params={}):
1654
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
1508
1655
  """
1509
1656
  fetch the trading fees for a market
1657
+
1658
+ https://huobiapi.github.io/docs/spot/v1/en/#get-current-fee-rate-applied-to-the-user
1659
+
1510
1660
  :param str symbol: unified market symbol
1511
1661
  :param dict [params]: extra parameters specific to the exchange API endpoint
1512
1662
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
1513
1663
  """
1514
1664
  await self.load_markets()
1515
1665
  market = self.market(symbol)
1516
- request = {
1666
+ request: dict = {
1517
1667
  'symbols': market['id'], # trading symbols comma-separated
1518
1668
  }
1519
1669
  response = await self.spotPrivateGetV2ReferenceTransactFeeRate(self.extend(request, params))
@@ -1543,14 +1693,23 @@ class htx(Exchange, ImplicitAPI):
1543
1693
  await self.load_markets()
1544
1694
  if symbols is None:
1545
1695
  symbols = self.symbols
1546
- result = {}
1696
+ result: dict = {}
1547
1697
  for i in range(0, len(symbols)):
1548
1698
  symbol = symbols[i]
1549
1699
  result[symbol] = await self.fetch_trading_limits_by_id(self.market_id(symbol), params)
1550
1700
  return result
1551
1701
 
1552
1702
  async def fetch_trading_limits_by_id(self, id: str, params={}):
1553
- request = {
1703
+ """
1704
+ @ignore
1705
+
1706
+ https://huobiapi.github.io/docs/spot/v1/en/#get-current-fee-rate-applied-to-the-user
1707
+
1708
+ :param str id: market id
1709
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1710
+ :returns dict: the limits object of a market structure
1711
+ """
1712
+ request: dict = {
1554
1713
  'symbol': id,
1555
1714
  }
1556
1715
  response = await self.spotPublicGetV1CommonExchange(self.extend(request, params))
@@ -1601,58 +1760,69 @@ class htx(Exchange, ImplicitAPI):
1601
1760
  def cost_to_precision(self, symbol, cost):
1602
1761
  return self.decimal_to_precision(cost, TRUNCATE, self.markets[symbol]['precision']['cost'], self.precisionMode)
1603
1762
 
1604
- async def fetch_markets(self, params={}):
1763
+ async def fetch_markets(self, params={}) -> List[Market]:
1605
1764
  """
1606
1765
  retrieves data on all markets for huobi
1766
+
1767
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
1768
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
1769
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
1770
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
1771
+
1607
1772
  :param dict [params]: extra parameters specific to the exchange API endpoint
1608
1773
  :returns dict[]: an array of objects representing market data
1609
1774
  """
1610
- options = self.safe_value(self.options, 'fetchMarkets', {})
1611
- types = self.safe_value(options, 'types', {})
1775
+ if self.options['adjustForTimeDifference']:
1776
+ await self.load_time_difference()
1777
+ types = None
1778
+ types, params = self.handle_option_and_params(params, 'fetchMarkets', 'types', {})
1612
1779
  allMarkets = []
1613
1780
  promises = []
1614
1781
  keys = list(types.keys())
1615
1782
  for i in range(0, len(keys)):
1616
- type = keys[i]
1617
- value = self.safe_value(types, type)
1618
- if value is True:
1619
- promises.append(self.fetch_markets_by_type_and_sub_type(type, None, params))
1620
- elif value:
1621
- subKeys = list(value.keys())
1622
- for j in range(0, len(subKeys)):
1623
- subType = subKeys[j]
1624
- subValue = self.safe_value(value, subType)
1625
- if subValue:
1626
- promises.append(self.fetch_markets_by_type_and_sub_type(type, subType, params))
1783
+ key = keys[i]
1784
+ if self.safe_bool(types, key):
1785
+ if key == 'spot':
1786
+ promises.append(self.fetch_markets_by_type_and_sub_type('spot', None, params))
1787
+ elif key == 'linear':
1788
+ promises.append(self.fetch_markets_by_type_and_sub_type(None, 'linear', params))
1789
+ elif key == 'inverse':
1790
+ promises.append(self.fetch_markets_by_type_and_sub_type('swap', 'inverse', params))
1791
+ promises.append(self.fetch_markets_by_type_and_sub_type('future', 'inverse', params))
1627
1792
  promises = await asyncio.gather(*promises)
1628
1793
  for i in range(0, len(promises)):
1629
1794
  allMarkets = self.array_concat(allMarkets, promises[i])
1630
1795
  return allMarkets
1631
1796
 
1632
- async def fetch_markets_by_type_and_sub_type(self, type, subType, params={}):
1633
- query = self.omit(params, ['type', 'subType'])
1634
- spot = (type == 'spot')
1635
- contract = (type != 'spot')
1636
- future = (type == 'future')
1637
- swap = (type == 'swap')
1638
- linear = None
1639
- inverse = None
1640
- request = {}
1797
+ async def fetch_markets_by_type_and_sub_type(self, type: Str, subType: Str, params={}):
1798
+ """
1799
+ @ignore
1800
+ retrieves data on all markets of a certain type and/or subtype
1801
+
1802
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
1803
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
1804
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
1805
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
1806
+
1807
+ :param str [type]: 'spot', 'swap' or 'future'
1808
+ :param str [subType]: 'linear' or 'inverse'
1809
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1810
+ :returns dict[]: an array of objects representing market data
1811
+ """
1812
+ isSpot = (type == 'spot')
1813
+ request: dict = {}
1641
1814
  response = None
1642
- if contract:
1643
- linear = (subType == 'linear')
1644
- inverse = (subType == 'inverse')
1645
- if linear:
1646
- if future:
1647
- request['business_type'] = 'futures'
1648
- response = await self.contractPublicGetLinearSwapApiV1SwapContractInfo(self.extend(request, query))
1649
- elif inverse:
1650
- if future:
1651
- response = await self.contractPublicGetApiV1ContractContractInfo(self.extend(request, query))
1652
- elif swap:
1653
- response = await self.contractPublicGetSwapApiV1SwapContractInfo(self.extend(request, query))
1815
+ if not isSpot:
1816
+ if subType == 'linear':
1817
+ request['business_type'] = 'all' # override default to fetch all linear markets
1818
+ response = await self.contractPublicGetLinearSwapApiV1SwapContractInfo(self.extend(request, params))
1819
+ elif subType == 'inverse':
1820
+ if type == 'future':
1821
+ response = await self.contractPublicGetApiV1ContractContractInfo(self.extend(request, params))
1822
+ elif type == 'swap':
1823
+ response = await self.contractPublicGetSwapApiV1SwapContractInfo(self.extend(request, params))
1654
1824
  else:
1655
- response = await self.spotPublicGetV1CommonSymbols(self.extend(request, query))
1825
+ response = await self.spotPublicGetV1CommonSymbols(self.extend(request, params))
1656
1826
  #
1657
1827
  # spot
1658
1828
  #
@@ -1691,75 +1861,58 @@ class htx(Exchange, ImplicitAPI):
1691
1861
  # ]
1692
1862
  # }
1693
1863
  #
1694
- # inverse future
1864
+ # inverse(swap & future)
1695
1865
  #
1696
1866
  # {
1697
1867
  # "status":"ok",
1698
1868
  # "data":[
1699
1869
  # {
1700
1870
  # "symbol":"BTC",
1701
- # "contract_code":"BTC211126",
1702
- # "contract_type":"self_week",
1703
- # "contract_size":100.000000000000000000,
1704
- # "price_tick":0.010000000000000000,
1705
- # "delivery_date":"20211126",
1706
- # "delivery_time":"1637913600000",
1871
+ # "contract_code":"BTC211126", #/ BTC-USD in swap
1872
+ # "contract_type":"self_week", # only in future
1873
+ # "contract_size":100,
1874
+ # "price_tick":0.1,
1875
+ # "delivery_date":"20211126", # only in future
1876
+ # "delivery_time":"1637913600000", # empty in swap
1707
1877
  # "create_date":"20211112",
1708
1878
  # "contract_status":1,
1709
- # "settlement_time":"1637481600000"
1879
+ # "settlement_time":"1637481600000" # only in future
1880
+ # "settlement_date":"16xxxxxxxxxxx" # only in swap
1710
1881
  # },
1882
+ # ...
1711
1883
  # ],
1712
1884
  # "ts":1637474595140
1713
1885
  # }
1714
1886
  #
1715
- # linear futures
1887
+ # linear(swap & future)
1716
1888
  #
1717
1889
  # {
1718
1890
  # "status":"ok",
1719
1891
  # "data":[
1720
1892
  # {
1721
1893
  # "symbol":"BTC",
1722
- # "contract_code":"BTC-USDT-211231",
1723
- # "contract_size":0.001000000000000000,
1724
- # "price_tick":0.100000000000000000,
1725
- # "delivery_date":"20211231",
1726
- # "delivery_time":"1640937600000",
1894
+ # "contract_code":"BTC-USDT-211231", # or "BTC-USDT" in swap
1895
+ # "contract_size":0.001,
1896
+ # "price_tick":0.1,
1897
+ # "delivery_date":"20211231", # empty in swap
1898
+ # "delivery_time":"1640937600000", # empty in swap
1727
1899
  # "create_date":"20211228",
1728
1900
  # "contract_status":1,
1729
1901
  # "settlement_date":"1640764800000",
1730
- # "support_margin_mode":"cross",
1731
- # "business_type":"futures",
1902
+ # "support_margin_mode":"cross", # "all" or "cross"
1903
+ # "business_type":"futures", # "swap" or "futures"
1732
1904
  # "pair":"BTC-USDT",
1733
- # "contract_type":"self_week" # next_week, quarter
1734
- # },
1905
+ # "contract_type":"self_week", # "swap", "self_week", "next_week", "quarter"
1906
+ # "trade_partition":"USDT",
1907
+ # }
1735
1908
  # ],
1736
1909
  # "ts":1640736207263
1737
1910
  # }
1738
1911
  #
1739
- # swaps
1740
- #
1741
- # {
1742
- # "status":"ok",
1743
- # "data":[
1744
- # {
1745
- # "symbol":"BTC",
1746
- # "contract_code":"BTC-USDT",
1747
- # "contract_size":0.001000000000000000,
1748
- # "price_tick":0.100000000000000000,
1749
- # "delivery_time":"",
1750
- # "create_date":"20201021",
1751
- # "contract_status":1,
1752
- # "settlement_date":"1637481600000",
1753
- # "support_margin_mode":"all", # isolated
1754
- # },
1755
- # ],
1756
- # "ts":1637474774467
1757
- # }
1758
- #
1759
- markets = self.safe_value(response, 'data', [])
1912
+ markets = self.safe_list(response, 'data', [])
1760
1913
  numMarkets = len(markets)
1761
1914
  if numMarkets < 1:
1762
- raise NetworkError(self.id + ' fetchMarkets() returned an empty response: ' + self.json(markets))
1915
+ raise OperationFailed(self.id + ' fetchMarkets() returned an empty response: ' + self.json(response))
1763
1916
  result = []
1764
1917
  for i in range(0, len(markets)):
1765
1918
  market = markets[i]
@@ -1768,15 +1921,30 @@ class htx(Exchange, ImplicitAPI):
1768
1921
  settleId = None
1769
1922
  id = None
1770
1923
  lowercaseId = None
1924
+ contract = ('contract_code' in market)
1925
+ spot = not contract
1926
+ swap = False
1927
+ future = False
1928
+ linear = None
1929
+ inverse = None
1930
+ # check if parsed market is contract
1771
1931
  if contract:
1772
1932
  id = self.safe_string(market, 'contract_code')
1773
1933
  lowercaseId = id.lower()
1934
+ delivery_date = self.safe_string(market, 'delivery_date')
1935
+ business_type = self.safe_string(market, 'business_type')
1936
+ future = delivery_date is not None
1937
+ swap = not future
1938
+ linear = business_type is not None
1939
+ inverse = not linear
1774
1940
  if swap:
1941
+ type = 'swap'
1775
1942
  parts = id.split('-')
1776
1943
  baseId = self.safe_string_lower(market, 'symbol')
1777
1944
  quoteId = self.safe_string_lower(parts, 1)
1778
1945
  settleId = baseId if inverse else quoteId
1779
1946
  elif future:
1947
+ type = 'future'
1780
1948
  baseId = self.safe_string_lower(market, 'symbol')
1781
1949
  if inverse:
1782
1950
  quoteId = 'USD'
@@ -1787,6 +1955,7 @@ class htx(Exchange, ImplicitAPI):
1787
1955
  quoteId = self.safe_string_lower(parts, 1)
1788
1956
  settleId = quoteId
1789
1957
  else:
1958
+ type = 'spot'
1790
1959
  baseId = self.safe_string(market, 'base-currency')
1791
1960
  quoteId = self.safe_string(market, 'quote-currency')
1792
1961
  id = baseId + quoteId
@@ -1909,7 +2078,41 @@ class htx(Exchange, ImplicitAPI):
1909
2078
  })
1910
2079
  return result
1911
2080
 
1912
- def parse_ticker(self, ticker, market: Market = None) -> Ticker:
2081
+ def try_get_symbol_from_future_markets(self, symbolOrMarketId: str):
2082
+ if symbolOrMarketId in self.markets:
2083
+ return symbolOrMarketId
2084
+ # only on "future" market type(inverse & linear), market-id differs between "fetchMarkets" and "fetchTicker"
2085
+ # so we have to create a mapping
2086
+ # - market-id from fetchMarkts: `BTC-USDT-240419`(linear future) or `BTC240412`(inverse future)
2087
+ # - market-id from fetchTciker[s]: `BTC-USDT-CW` (linear future) or `BTC_CW` (inverse future)
2088
+ if not ('futureMarketIdsForSymbols' in self.options):
2089
+ self.options['futureMarketIdsForSymbols'] = {}
2090
+ futureMarketIdsForSymbols = self.safe_dict(self.options, 'futureMarketIdsForSymbols', {})
2091
+ if symbolOrMarketId in futureMarketIdsForSymbols:
2092
+ return futureMarketIdsForSymbols[symbolOrMarketId]
2093
+ futureMarkets = self.filter_by(self.markets, 'future', True)
2094
+ futuresCharsMaps: dict = {
2095
+ 'this_week': 'CW',
2096
+ 'next_week': 'NW',
2097
+ 'quarter': 'CQ',
2098
+ 'next_quarter': 'NQ',
2099
+ }
2100
+ for i in range(0, len(futureMarkets)):
2101
+ market = futureMarkets[i]
2102
+ info = self.safe_value(market, 'info', {})
2103
+ contractType = self.safe_string(info, 'contract_type')
2104
+ contractSuffix = futuresCharsMaps[contractType]
2105
+ # see comment on formats a bit above
2106
+ constructedId = market['base'] + '-' + market['quote'] + '-' + contractSuffix if market['linear'] else market['base'] + '_' + contractSuffix
2107
+ if constructedId == symbolOrMarketId:
2108
+ symbol = market['symbol']
2109
+ self.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbol
2110
+ return symbol
2111
+ # if not found, just save it to avoid unnecessary future iterations
2112
+ self.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbolOrMarketId
2113
+ return symbolOrMarketId
2114
+
2115
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1913
2116
  #
1914
2117
  # fetchTicker
1915
2118
  #
@@ -1957,6 +2160,7 @@ class htx(Exchange, ImplicitAPI):
1957
2160
  #
1958
2161
  marketId = self.safe_string_2(ticker, 'symbol', 'contract_code')
1959
2162
  symbol = self.safe_symbol(marketId, market)
2163
+ symbol = self.try_get_symbol_from_future_markets(symbol)
1960
2164
  timestamp = self.safe_integer_2(ticker, 'ts', 'quoteTime')
1961
2165
  bid = None
1962
2166
  bidVolume = None
@@ -2006,13 +2210,19 @@ class htx(Exchange, ImplicitAPI):
2006
2210
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2007
2211
  """
2008
2212
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
2213
+
2214
+ https://huobiapi.github.io/docs/spot/v1/en/#get-latest-aggregated-ticker
2215
+ https://huobiapi.github.io/docs/dm/v1/en/#get-market-data-overview
2216
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-data-overview
2217
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-data-overview
2218
+
2009
2219
  :param str symbol: unified symbol of the market to fetch the ticker for
2010
2220
  :param dict [params]: extra parameters specific to the exchange API endpoint
2011
2221
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
2012
2222
  """
2013
2223
  await self.load_markets()
2014
2224
  market = self.market(symbol)
2015
- request = {}
2225
+ request: dict = {}
2016
2226
  response = None
2017
2227
  if market['linear']:
2018
2228
  request['contract_code'] = market['id']
@@ -2080,11 +2290,13 @@ class htx(Exchange, ImplicitAPI):
2080
2290
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
2081
2291
  """
2082
2292
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
2083
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-latest-tickers-for-all-pairs
2084
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
2085
- :see: https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
2086
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
2087
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2293
+
2294
+ https://huobiapi.github.io/docs/spot/v1/en/#get-latest-tickers-for-all-pairs
2295
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
2296
+ https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
2297
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
2298
+
2299
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2088
2300
  :param dict [params]: extra parameters specific to the exchange API endpoint
2089
2301
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2090
2302
  """
@@ -2094,27 +2306,37 @@ class htx(Exchange, ImplicitAPI):
2094
2306
  market = None
2095
2307
  if first is not None:
2096
2308
  market = self.market(first)
2309
+ isSubTypeRequested = ('subType' in params) or ('business_type' in params)
2097
2310
  type = None
2098
2311
  subType = None
2099
2312
  type, params = self.handle_market_type_and_params('fetchTickers', market, params)
2100
2313
  subType, params = self.handle_sub_type_and_params('fetchTickers', market, params)
2101
- request = {}
2314
+ request: dict = {}
2315
+ isSpot = (type == 'spot')
2102
2316
  future = (type == 'future')
2103
2317
  swap = (type == 'swap')
2104
2318
  linear = (subType == 'linear')
2105
2319
  inverse = (subType == 'inverse')
2106
- params = self.omit(params, ['type', 'subType'])
2107
2320
  response = None
2108
- if future or swap:
2321
+ if not isSpot or isSubTypeRequested:
2109
2322
  if linear:
2323
+ # independently of type, supports calling all linear symbols i.e. fetchTickers(None, {subType:'linear'})
2110
2324
  if future:
2111
2325
  request['business_type'] = 'futures'
2326
+ elif swap:
2327
+ request['business_type'] = 'swap'
2328
+ else:
2329
+ request['business_type'] = 'all'
2112
2330
  response = await self.contractPublicGetLinearSwapExMarketDetailBatchMerged(self.extend(request, params))
2113
2331
  elif inverse:
2114
2332
  if future:
2115
2333
  response = await self.contractPublicGetMarketDetailBatchMerged(self.extend(request, params))
2116
2334
  elif swap:
2117
2335
  response = await self.contractPublicGetSwapExMarketDetailBatchMerged(self.extend(request, params))
2336
+ else:
2337
+ raise NotSupported(self.id + ' fetchTickers() you have to set params["type"] to either "swap" or "future" for inverse contracts')
2338
+ else:
2339
+ raise NotSupported(self.id + ' fetchTickers() you have to set params["subType"] to either "linear" or "inverse" for contracts')
2118
2340
  else:
2119
2341
  response = await self.spotPublicGetMarketTickers(self.extend(request, params))
2120
2342
  #
@@ -2141,7 +2363,7 @@ class htx(Exchange, ImplicitAPI):
2141
2363
  # "ts":1639547261293
2142
2364
  # }
2143
2365
  #
2144
- # inverse swaps, linear swaps, inverse futures
2366
+ # linear swap, linear future, inverse swap, inverse future
2145
2367
  #
2146
2368
  # {
2147
2369
  # "status":"ok",
@@ -2158,74 +2380,28 @@ class htx(Exchange, ImplicitAPI):
2158
2380
  # "high":"0.10725",
2159
2381
  # "amount":"2340267.415144052378486261756692535687481566",
2160
2382
  # "count":882,
2161
- # "vol":"24706"
2383
+ # "vol":"24706",
2384
+ # "trade_turnover":"840726.5048", # only in linear futures
2385
+ # "business_type":"futures", # only in linear futures
2386
+ # "contract_code":"BTC-USDT-CW", # only in linear futures, instead of 'symbol'
2162
2387
  # }
2163
2388
  # ],
2164
2389
  # "ts":1637504679376
2165
2390
  # }
2166
2391
  #
2167
- # linear futures
2168
- #
2169
- # {
2170
- # "status":"ok",
2171
- # "ticks":[
2172
- # {
2173
- # "id":1640745627,
2174
- # "ts":1640745627957,
2175
- # "ask":[48079.1,20],
2176
- # "bid":[47713.8,125],
2177
- # "business_type":"futures",
2178
- # "contract_code":"BTC-USDT-CW",
2179
- # "open":"49011.8",
2180
- # "close":"47934",
2181
- # "low":"47292.3",
2182
- # "high":"49011.8",
2183
- # "amount":"17.398",
2184
- # "count":1515,
2185
- # "vol":"17398",
2186
- # "trade_turnover":"840726.5048"
2187
- # }
2188
- # ],
2189
- # "ts":1640745627988
2190
- # }
2191
- #
2192
- tickers = self.safe_value_2(response, 'data', 'ticks', [])
2193
- timestamp = self.safe_integer(response, 'ts')
2194
- result = {}
2195
- for i in range(0, len(tickers)):
2196
- ticker = self.parse_ticker(tickers[i])
2197
- # the market ids for linear futures are non-standard and differ from all the other endpoints
2198
- # we are doing a linear-matching here
2199
- if future and linear:
2200
- for j in range(0, len(self.symbols)):
2201
- symbolInner = self.symbols[j]
2202
- marketInner = self.market(symbolInner)
2203
- contractType = self.safe_string(marketInner['info'], 'contract_type')
2204
- if (contractType == 'this_week') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CW')):
2205
- ticker['symbol'] = marketInner['symbol']
2206
- break
2207
- elif (contractType == 'next_week') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NW')):
2208
- ticker['symbol'] = marketInner['symbol']
2209
- break
2210
- elif (contractType == 'this_quarter') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CQ')):
2211
- ticker['symbol'] = marketInner['symbol']
2212
- break
2213
- elif (contractType == 'next_quarter') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NQ')):
2214
- ticker['symbol'] = marketInner['symbol']
2215
- break
2216
- symbol = ticker['symbol']
2217
- ticker['timestamp'] = timestamp
2218
- ticker['datetime'] = self.iso8601(timestamp)
2219
- result[symbol] = ticker
2220
- return self.filter_by_array_tickers(result, 'symbol', symbols)
2392
+ rawTickers = self.safe_list_2(response, 'data', 'ticks', [])
2393
+ tickers = self.parse_tickers(rawTickers, symbols, params)
2394
+ return self.filter_by_array_tickers(tickers, 'symbol', symbols)
2221
2395
 
2222
2396
  async def fetch_last_prices(self, symbols: Strings = None, params={}):
2223
2397
  """
2224
2398
  fetches the last price for multiple markets
2225
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2226
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2227
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2228
- :param str[]|None symbols: unified symbols of the markets to fetch the last prices
2399
+
2400
+ https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2401
+ https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2402
+ https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2403
+
2404
+ :param str[] [symbols]: unified symbols of the markets to fetch the last prices
2229
2405
  :param dict [params]: extra parameters specific to the exchange API endpoint
2230
2406
  :returns dict: a dictionary of lastprices structures
2231
2407
  """
@@ -2315,7 +2491,7 @@ class htx(Exchange, ImplicitAPI):
2315
2491
  else:
2316
2492
  raise NotSupported(self.id + ' fetchLastPrices() does not support ' + type + ' markets yet')
2317
2493
  tick = self.safe_value(response, 'tick', {})
2318
- data = self.safe_value(tick, 'data', [])
2494
+ data = self.safe_list(tick, 'data', [])
2319
2495
  return self.parse_last_prices(data, symbols)
2320
2496
 
2321
2497
  def parse_last_price(self, entry, market: Market = None):
@@ -2337,6 +2513,12 @@ class htx(Exchange, ImplicitAPI):
2337
2513
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2338
2514
  """
2339
2515
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
2516
+
2517
+ https://huobiapi.github.io/docs/spot/v1/en/#get-market-depth
2518
+ https://huobiapi.github.io/docs/dm/v1/en/#get-market-depth
2519
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-depth
2520
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-depth
2521
+
2340
2522
  :param str symbol: unified symbol of the market to fetch the order book for
2341
2523
  :param int [limit]: the maximum amount of order book entries to return
2342
2524
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2344,7 +2526,7 @@ class htx(Exchange, ImplicitAPI):
2344
2526
  """
2345
2527
  await self.load_markets()
2346
2528
  market = self.market(symbol)
2347
- request = {
2529
+ request: dict = {
2348
2530
  #
2349
2531
  # from the API docs
2350
2532
  #
@@ -2414,7 +2596,7 @@ class htx(Exchange, ImplicitAPI):
2414
2596
  return result
2415
2597
  raise ExchangeError(self.id + ' fetchOrderBook() returned unrecognized response: ' + self.json(response))
2416
2598
 
2417
- def parse_trade(self, trade, market: Market = None) -> Trade:
2599
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
2418
2600
  #
2419
2601
  # spot fetchTrades(public)
2420
2602
  #
@@ -2548,6 +2730,9 @@ class htx(Exchange, ImplicitAPI):
2548
2730
  async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2549
2731
  """
2550
2732
  fetch all the trades made from a single order
2733
+
2734
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2735
+
2551
2736
  :param str id: order id
2552
2737
  :param str symbol: unified market symbol
2553
2738
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2565,8 +2750,21 @@ class htx(Exchange, ImplicitAPI):
2565
2750
  return await self.fetch_spot_order_trades(id, symbol, since, limit, params)
2566
2751
 
2567
2752
  async def fetch_spot_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2753
+ """
2754
+ @ignore
2755
+ fetch all the trades made from a single order
2756
+
2757
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2758
+
2759
+ :param str id: order id
2760
+ :param str symbol: unified market symbol
2761
+ :param int [since]: the earliest time in ms to fetch trades for
2762
+ :param int [limit]: the maximum number of trades to retrieve
2763
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2764
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2765
+ """
2568
2766
  await self.load_markets()
2569
- request = {
2767
+ request: dict = {
2570
2768
  'order-id': id,
2571
2769
  }
2572
2770
  response = await self.spotPrivateGetV1OrderOrdersOrderIdMatchresults(self.extend(request, params))
@@ -2574,9 +2772,11 @@ class htx(Exchange, ImplicitAPI):
2574
2772
 
2575
2773
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2576
2774
  """
2577
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-match-results-via-multiple-fields-new
2578
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-match-results-via-multiple-fields-new
2579
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-match-results
2775
+
2776
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-match-results-via-multiple-fields-new
2777
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-match-results-via-multiple-fields-new
2778
+ https://huobiapi.github.io/docs/spot/v1/en/#search-match-results
2779
+
2580
2780
  fetch all trades made by the user
2581
2781
  :param str symbol: unified market symbol
2582
2782
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2596,7 +2796,7 @@ class htx(Exchange, ImplicitAPI):
2596
2796
  market = self.market(symbol)
2597
2797
  marketType = None
2598
2798
  marketType, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
2599
- request = {
2799
+ request: dict = {
2600
2800
  # spot -----------------------------------------------------------
2601
2801
  # 'symbol': market['id'],
2602
2802
  # 'types': 'buy-market,sell-market,buy-limit,sell-limit,buy-ioc,sell-ioc,buy-limit-maker,sell-limit-maker,buy-stop-limit,sell-stop-limit',
@@ -2727,10 +2927,12 @@ class htx(Exchange, ImplicitAPI):
2727
2927
 
2728
2928
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = 1000, params={}) -> List[Trade]:
2729
2929
  """
2730
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-most-recent-trades
2731
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-a-batch-of-trade-records-of-a-contract
2732
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-trade-records-of-a-contract
2733
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-trade-records-of-a-contract
2930
+
2931
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-most-recent-trades
2932
+ https://huobiapi.github.io/docs/dm/v1/en/#query-a-batch-of-trade-records-of-a-contract
2933
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-trade-records-of-a-contract
2934
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-trade-records-of-a-contract
2935
+
2734
2936
  get the list of most recent trades for a particular symbol
2735
2937
  :param str symbol: unified symbol of the market to fetch trades for
2736
2938
  :param int [since]: timestamp in ms of the earliest trade to fetch
@@ -2740,7 +2942,7 @@ class htx(Exchange, ImplicitAPI):
2740
2942
  """
2741
2943
  await self.load_markets()
2742
2944
  market = self.market(symbol)
2743
- request = {
2945
+ request: dict = {
2744
2946
  # 'symbol': market['id'], # spot, future
2745
2947
  # 'contract_code': market['id'], # swap
2746
2948
  }
@@ -2822,10 +3024,12 @@ class htx(Exchange, ImplicitAPI):
2822
3024
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
2823
3025
  """
2824
3026
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
2825
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles
2826
- :see: https://huobiapi.github.io/docs/dm/v1/en/#get-kline-data
2827
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-kline-data
2828
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
3027
+
3028
+ https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles
3029
+ https://huobiapi.github.io/docs/dm/v1/en/#get-kline-data
3030
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-kline-data
3031
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
3032
+
2829
3033
  :param str symbol: unified symbol of the market to fetch OHLCV data for
2830
3034
  :param str timeframe: the length of time each candle represents
2831
3035
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -2841,7 +3045,7 @@ class htx(Exchange, ImplicitAPI):
2841
3045
  if paginate:
2842
3046
  return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000)
2843
3047
  market = self.market(symbol)
2844
- request = {
3048
+ request: dict = {
2845
3049
  'period': self.safe_string(self.timeframes, timeframe, timeframe),
2846
3050
  # 'symbol': market['id'], # spot, future
2847
3051
  # 'contract_code': market['id'], # swap
@@ -2849,63 +3053,68 @@ class htx(Exchange, ImplicitAPI):
2849
3053
  # 'from': int((since / str(1000))), spot only
2850
3054
  # 'to': self.seconds(), spot only
2851
3055
  }
2852
- price = self.safe_string(params, 'price')
2853
- params = self.omit(params, 'price')
3056
+ priceType = self.safe_string_n(params, ['priceType', 'price'])
3057
+ params = self.omit(params, ['priceType', 'price'])
3058
+ until = None
3059
+ until, params = self.handle_param_integer(params, 'until')
3060
+ untilSeconds = self.parse_to_int(until / 1000) if (until is not None) else None
2854
3061
  if market['contract']:
2855
3062
  if limit is not None:
2856
- request['size'] = limit # when using limit from and to are ignored
3063
+ request['size'] = min(limit, 2000) # when using limit: from & to are ignored
2857
3064
  # https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
2858
3065
  else:
2859
3066
  limit = 2000 # only used for from/to calculation
2860
- if price is None:
3067
+ if priceType is None:
2861
3068
  duration = self.parse_timeframe(timeframe)
3069
+ calcualtedEnd = None
2862
3070
  if since is None:
2863
3071
  now = self.seconds()
2864
3072
  request['from'] = now - duration * (limit - 1)
2865
- request['to'] = now
3073
+ calcualtedEnd = now
2866
3074
  else:
2867
3075
  start = self.parse_to_int(since / 1000)
2868
3076
  request['from'] = start
2869
- request['to'] = self.sum(start, duration * (limit - 1))
3077
+ calcualtedEnd = self.sum(start, duration * (limit - 1))
3078
+ request['to'] = untilSeconds if (untilSeconds is not None) else calcualtedEnd
2870
3079
  response = None
2871
3080
  if market['future']:
2872
3081
  if market['inverse']:
2873
3082
  request['symbol'] = market['id']
2874
- if price == 'mark':
3083
+ if priceType == 'mark':
2875
3084
  response = await self.contractPublicGetIndexMarketHistoryMarkPriceKline(self.extend(request, params))
2876
- elif price == 'index':
3085
+ elif priceType == 'index':
2877
3086
  response = await self.contractPublicGetIndexMarketHistoryIndex(self.extend(request, params))
2878
- elif price == 'premiumIndex':
2879
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
3087
+ elif priceType == 'premiumIndex':
3088
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
2880
3089
  else:
2881
3090
  response = await self.contractPublicGetMarketHistoryKline(self.extend(request, params))
2882
3091
  elif market['linear']:
2883
3092
  request['contract_code'] = market['id']
2884
- if price == 'mark':
3093
+ if priceType == 'mark':
2885
3094
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(self.extend(request, params))
2886
- elif price == 'index':
2887
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2888
- elif price == 'premiumIndex':
3095
+ elif priceType == 'index':
3096
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
3097
+ elif priceType == 'premiumIndex':
2889
3098
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(self.extend(request, params))
2890
3099
  else:
2891
3100
  response = await self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
2892
3101
  elif market['swap']:
2893
3102
  request['contract_code'] = market['id']
2894
3103
  if market['inverse']:
2895
- if price == 'mark':
3104
+ if priceType == 'mark':
2896
3105
  response = await self.contractPublicGetIndexMarketHistorySwapMarkPriceKline(self.extend(request, params))
2897
- elif price == 'index':
2898
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2899
- elif price == 'premiumIndex':
3106
+ elif priceType == 'index':
3107
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
3108
+ elif priceType == 'premiumIndex':
2900
3109
  response = await self.contractPublicGetIndexMarketHistorySwapPremiumIndexKline(self.extend(request, params))
2901
3110
  else:
2902
3111
  response = await self.contractPublicGetSwapExMarketHistoryKline(self.extend(request, params))
2903
3112
  elif market['linear']:
2904
- if price == 'mark':
3113
+ if priceType == 'mark':
2905
3114
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(self.extend(request, params))
2906
- elif price == 'index':
2907
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2908
- elif price == 'premiumIndex':
3115
+ elif priceType == 'index':
3116
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
3117
+ elif priceType == 'premiumIndex':
2909
3118
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(self.extend(request, params))
2910
3119
  else:
2911
3120
  response = await self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
@@ -2914,15 +3123,17 @@ class htx(Exchange, ImplicitAPI):
2914
3123
  useHistorical = None
2915
3124
  useHistorical, params = self.handle_option_and_params(params, 'fetchOHLCV', 'useHistoricalEndpointForSpot', True)
2916
3125
  if not useHistorical:
2917
- # `limit` only available for the self endpoint
2918
3126
  if limit is not None:
2919
- request['size'] = limit # max 2000
3127
+ request['size'] = min(limit, 2000) # max 2000
2920
3128
  response = await self.spotPublicGetMarketHistoryKline(self.extend(request, params))
2921
3129
  else:
2922
- # `since` only available for the self endpoint
3130
+ # "from & to" only available for the self endpoint
2923
3131
  if since is not None:
2924
- # default 150 bars
2925
3132
  request['from'] = self.parse_to_int(since / 1000)
3133
+ if untilSeconds is not None:
3134
+ request['to'] = untilSeconds
3135
+ if limit is not None:
3136
+ request['size'] = min(1000, limit) # max 1000, otherwise default returns 150
2926
3137
  response = await self.spotPublicGetMarketHistoryCandles(self.extend(request, params))
2927
3138
  #
2928
3139
  # {
@@ -2936,12 +3147,15 @@ class htx(Exchange, ImplicitAPI):
2936
3147
  # ]
2937
3148
  # }
2938
3149
  #
2939
- data = self.safe_value(response, 'data', [])
3150
+ data = self.safe_list(response, 'data', [])
2940
3151
  return self.parse_ohlcvs(data, market, timeframe, since, limit)
2941
3152
 
2942
3153
  async def fetch_accounts(self, params={}) -> List[Account]:
2943
3154
  """
2944
3155
  fetch all the accounts associated with a profile
3156
+
3157
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user
3158
+
2945
3159
  :param dict [params]: extra parameters specific to the exchange API endpoint
2946
3160
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
2947
3161
  """
@@ -2978,7 +3192,18 @@ class htx(Exchange, ImplicitAPI):
2978
3192
  'code': None,
2979
3193
  }
2980
3194
 
2981
- async def fetch_account_id_by_type(self, type, marginMode=None, symbol=None, params={}):
3195
+ async def fetch_account_id_by_type(self, type: str, marginMode: Str = None, symbol: Str = None, params={}):
3196
+ """
3197
+ fetch all the accounts by a type and marginModeassociated with a profile
3198
+
3199
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user
3200
+
3201
+ :param str type: 'spot', 'swap' or 'future
3202
+ :param str [marginMode]: 'cross' or 'isolated'
3203
+ :param str [symbol]: unified ccxt market symbol
3204
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3205
+ :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
3206
+ """
2982
3207
  accounts = await self.load_accounts()
2983
3208
  accountId = self.safe_value_2(params, 'accountId', 'account-id')
2984
3209
  if accountId is not None:
@@ -3002,9 +3227,12 @@ class htx(Exchange, ImplicitAPI):
3002
3227
  defaultAccount = self.safe_value(accounts, 0, {})
3003
3228
  return self.safe_string(defaultAccount, 'id')
3004
3229
 
3005
- async def fetch_currencies(self, params={}):
3230
+ async def fetch_currencies(self, params={}) -> Currencies:
3006
3231
  """
3007
3232
  fetches all available currencies on an exchange
3233
+
3234
+ https://huobiapi.github.io/docs/spot/v1/en/#apiv2-currency-amp-chains
3235
+
3008
3236
  :param dict [params]: extra parameters specific to the exchange API endpoint
3009
3237
  :returns dict: an associative dictionary of currencies
3010
3238
  """
@@ -3047,7 +3275,7 @@ class htx(Exchange, ImplicitAPI):
3047
3275
  # }
3048
3276
  #
3049
3277
  data = self.safe_value(response, 'data', [])
3050
- result = {}
3278
+ result: dict = {}
3051
3279
  self.options['networkChainIdsByNames'] = {}
3052
3280
  self.options['networkNamesByChainIds'] = {}
3053
3281
  for i in range(0, len(data)):
@@ -3056,10 +3284,11 @@ class htx(Exchange, ImplicitAPI):
3056
3284
  code = self.safe_currency_code(currencyId)
3057
3285
  self.options['networkChainIdsByNames'][code] = {}
3058
3286
  chains = self.safe_value(entry, 'chains', [])
3059
- networks = {}
3287
+ networks: dict = {}
3060
3288
  instStatus = self.safe_string(entry, 'instStatus')
3061
3289
  currencyActive = instStatus == 'normal'
3062
3290
  minPrecision = None
3291
+ minDeposit = None
3063
3292
  minWithdraw = None
3064
3293
  maxWithdraw = None
3065
3294
  deposit = False
@@ -3071,6 +3300,7 @@ class htx(Exchange, ImplicitAPI):
3071
3300
  self.options['networkChainIdsByNames'][code][title] = uniqueChainId
3072
3301
  self.options['networkNamesByChainIds'][uniqueChainId] = title
3073
3302
  networkCode = self.network_id_to_code(uniqueChainId)
3303
+ minDeposit = self.safe_number(chainEntry, 'minDepositAmt')
3074
3304
  minWithdraw = self.safe_number(chainEntry, 'minWithdrawAmt')
3075
3305
  maxWithdraw = self.safe_number(chainEntry, 'maxWithdrawAmt')
3076
3306
  withdrawStatus = self.safe_string(chainEntry, 'withdrawStatus')
@@ -3090,7 +3320,7 @@ class htx(Exchange, ImplicitAPI):
3090
3320
  'network': networkCode,
3091
3321
  'limits': {
3092
3322
  'deposit': {
3093
- 'min': None,
3323
+ 'min': minDeposit,
3094
3324
  'max': None,
3095
3325
  },
3096
3326
  'withdraw': {
@@ -3132,7 +3362,7 @@ class htx(Exchange, ImplicitAPI):
3132
3362
  }
3133
3363
  return result
3134
3364
 
3135
- def network_id_to_code(self, networkId, currencyCode=None):
3365
+ def network_id_to_code(self, networkId: Str = None, currencyCode: Str = None):
3136
3366
  # here network-id is provided pair of currency & chain(i.e. trc20usdt)
3137
3367
  keys = list(self.options['networkNamesByChainIds'].keys())
3138
3368
  keysLength = len(keys)
@@ -3141,7 +3371,7 @@ class htx(Exchange, ImplicitAPI):
3141
3371
  networkTitle = self.safe_value(self.options['networkNamesByChainIds'], networkId, networkId)
3142
3372
  return super(htx, self).network_id_to_code(networkTitle)
3143
3373
 
3144
- def network_code_to_id(self, networkCode, currencyCode=None):
3374
+ def network_code_to_id(self, networkCode: str, currencyCode: Str = None):
3145
3375
  if currencyCode is None:
3146
3376
  raise ArgumentsRequired(self.id + ' networkCodeToId() requires a currencyCode argument')
3147
3377
  keys = list(self.options['networkChainIdsByNames'].keys())
@@ -3157,13 +3387,15 @@ class htx(Exchange, ImplicitAPI):
3157
3387
 
3158
3388
  async def fetch_balance(self, params={}) -> Balances:
3159
3389
  """
3160
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-account-balance-of-a-specific-account
3161
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec4b429-7773-11ed-9966-0242ac110003
3162
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=10000074-77b7-11ed-9966-0242ac110003
3163
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-asset-valuation
3164
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-account-information
3165
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-account-information
3166
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-account-information
3390
+
3391
+ https://huobiapi.github.io/docs/spot/v1/en/#get-account-balance-of-a-specific-account
3392
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4b429-7773-11ed-9966-0242ac110003
3393
+ https://www.htx.com/en-us/opend/newApiPages/?id=10000074-77b7-11ed-9966-0242ac110003
3394
+ https://huobiapi.github.io/docs/dm/v1/en/#query-asset-valuation
3395
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-account-information
3396
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-account-information
3397
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-account-information
3398
+
3167
3399
  query for balance and get the amount of funds available for trading or funds locked in orders
3168
3400
  :param dict [params]: extra parameters specific to the exchange API endpoint
3169
3401
  :param bool [params.unified]: provide self parameter if you have a recent account with unified cross+isolated margin account
@@ -3175,7 +3407,7 @@ class htx(Exchange, ImplicitAPI):
3175
3407
  options = self.safe_value(self.options, 'fetchBalance', {})
3176
3408
  isUnifiedAccount = self.safe_value_2(params, 'isUnifiedAccount', 'unified', False)
3177
3409
  params = self.omit(params, ['isUnifiedAccount', 'unified'])
3178
- request = {}
3410
+ request: dict = {}
3179
3411
  spot = (type == 'spot')
3180
3412
  future = (type == 'future')
3181
3413
  defaultSubType = self.safe_string_2(self.options, 'defaultSubType', 'subType', 'linear')
@@ -3372,7 +3604,7 @@ class htx(Exchange, ImplicitAPI):
3372
3604
  #
3373
3605
  # TODO add balance parsing for linear swap
3374
3606
  #
3375
- result = {'info': response}
3607
+ result: dict = {'info': response}
3376
3608
  data = self.safe_value(response, 'data')
3377
3609
  if spot or margin:
3378
3610
  if isolated:
@@ -3380,7 +3612,7 @@ class htx(Exchange, ImplicitAPI):
3380
3612
  entry = data[i]
3381
3613
  symbol = self.safe_symbol(self.safe_string(entry, 'symbol'))
3382
3614
  balances = self.safe_value(entry, 'list')
3383
- subResult = {}
3615
+ subResult: dict = {}
3384
3616
  for j in range(0, len(balances)):
3385
3617
  balance = balances[j]
3386
3618
  currencyId = self.safe_string(balance, 'currency')
@@ -3405,7 +3637,7 @@ class htx(Exchange, ImplicitAPI):
3405
3637
  for j in range(0, len(isolated_swap)):
3406
3638
  balance = isolated_swap[j]
3407
3639
  marketId = self.safe_string(balance, 'contract_code')
3408
- subBalance = {
3640
+ subBalance: dict = {
3409
3641
  'code': currencyCode,
3410
3642
  'free': self.safe_number(balance, 'margin_available'),
3411
3643
  }
@@ -3435,7 +3667,7 @@ class htx(Exchange, ImplicitAPI):
3435
3667
  account = self.account()
3436
3668
  account['free'] = self.safe_string(balance, 'margin_balance')
3437
3669
  account['used'] = self.safe_string(balance, 'margin_frozen')
3438
- accountsByCode = {}
3670
+ accountsByCode: dict = {}
3439
3671
  accountsByCode[code] = account
3440
3672
  symbol = market['symbol']
3441
3673
  result[symbol] = self.safe_balance(accountsByCode)
@@ -3462,6 +3694,15 @@ class htx(Exchange, ImplicitAPI):
3462
3694
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
3463
3695
  """
3464
3696
  fetches information on an order made by the user
3697
+
3698
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order-based-on-client-order-id
3699
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order
3700
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-information-of-an-order
3701
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-information-of-order
3702
+ https://huobiapi.github.io/docs/dm/v1/en/#get-information-of-an-order
3703
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-information-of-an-order
3704
+
3705
+ :param str id: order id
3465
3706
  :param str symbol: unified symbol of the market the order was made in
3466
3707
  :param dict [params]: extra parameters specific to the exchange API endpoint
3467
3708
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -3472,7 +3713,7 @@ class htx(Exchange, ImplicitAPI):
3472
3713
  market = self.market(symbol)
3473
3714
  marketType = None
3474
3715
  marketType, params = self.handle_market_type_and_params('fetchOrder', market, params)
3475
- request = {
3716
+ request: dict = {
3476
3717
  # spot -----------------------------------------------------------
3477
3718
  # 'order-id': 'id',
3478
3719
  # 'symbol': market['id'],
@@ -3671,7 +3912,7 @@ class htx(Exchange, ImplicitAPI):
3671
3912
  raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
3672
3913
  await self.load_markets()
3673
3914
  market = None
3674
- request = {
3915
+ request: dict = {
3675
3916
  # spot_private_get_v1_order_orders GET /v1/order/orders ----------
3676
3917
  # 'symbol': market['id'], # required
3677
3918
  # 'types': 'buy-market,sell-market,buy-limit,sell-limit,buy-ioc,sell-ioc,buy-stop-limit,sell-stop-limit,buy-limit-fok,sell-limit-fok,buy-stop-limit-fok,sell-stop-limit-fok',
@@ -3728,7 +3969,7 @@ class htx(Exchange, ImplicitAPI):
3728
3969
  # ]
3729
3970
  # }
3730
3971
  #
3731
- data = self.safe_value(response, 'data', [])
3972
+ data = self.safe_list(response, 'data', [])
3732
3973
  return self.parse_orders(data, market, since, limit)
3733
3974
 
3734
3975
  async def fetch_spot_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -3742,7 +3983,7 @@ class htx(Exchange, ImplicitAPI):
3742
3983
  raise ArgumentsRequired(self.id + ' fetchContractOrders() requires a symbol argument')
3743
3984
  await self.load_markets()
3744
3985
  market = self.market(symbol)
3745
- request = {
3986
+ request: dict = {
3746
3987
  # POST /api/v1/contract_hisorders inverse futures ----------------
3747
3988
  # 'symbol': market['settleId'], # BTC, ETH, ...
3748
3989
  # 'order_type': '1', # 1 limit,3 opponent,4 lightning, 5 trigger order, 6 pst_only, 7 optimal_5, 8 optimal_10, 9 optimal_20, 10 fok, 11 ioc
@@ -3753,11 +3994,11 @@ class htx(Exchange, ImplicitAPI):
3753
3994
  'status': '0', # support multiple query seperated by ',',such as '3,4,5', 0: all. 3. Have sumbmitted the orders; 4. Orders partially matched; 5. Orders cancelled with partially matched; 6. Orders fully matched; 7. Orders cancelled
3754
3995
  }
3755
3996
  response = None
3756
- stop = self.safe_value(params, 'stop')
3997
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
3757
3998
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
3758
3999
  trailing = self.safe_bool(params, 'trailing', False)
3759
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
3760
- if stop or stopLossTakeProfit or trailing:
4000
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
4001
+ if trigger or stopLossTakeProfit or trailing:
3761
4002
  if limit is not None:
3762
4003
  request['page_size'] = limit
3763
4004
  request['contract_code'] = market['id']
@@ -3774,7 +4015,7 @@ class htx(Exchange, ImplicitAPI):
3774
4015
  marginMode, params = self.handle_margin_mode_and_params('fetchContractOrders', params)
3775
4016
  marginMode = 'cross' if (marginMode is None) else marginMode
3776
4017
  if marginMode == 'isolated':
3777
- if stop:
4018
+ if trigger:
3778
4019
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerHisorders(self.extend(request, params))
3779
4020
  elif stopLossTakeProfit:
3780
4021
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslHisorders(self.extend(request, params))
@@ -3783,7 +4024,7 @@ class htx(Exchange, ImplicitAPI):
3783
4024
  else:
3784
4025
  response = await self.contractPrivatePostLinearSwapApiV3SwapHisorders(self.extend(request, params))
3785
4026
  elif marginMode == 'cross':
3786
- if stop:
4027
+ if trigger:
3787
4028
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerHisorders(self.extend(request, params))
3788
4029
  elif stopLossTakeProfit:
3789
4030
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslHisorders(self.extend(request, params))
@@ -3793,7 +4034,7 @@ class htx(Exchange, ImplicitAPI):
3793
4034
  response = await self.contractPrivatePostLinearSwapApiV3SwapCrossHisorders(self.extend(request, params))
3794
4035
  elif market['inverse']:
3795
4036
  if market['swap']:
3796
- if stop:
4037
+ if trigger:
3797
4038
  response = await self.contractPrivatePostSwapApiV1SwapTriggerHisorders(self.extend(request, params))
3798
4039
  elif stopLossTakeProfit:
3799
4040
  response = await self.contractPrivatePostSwapApiV1SwapTpslHisorders(self.extend(request, params))
@@ -3803,7 +4044,7 @@ class htx(Exchange, ImplicitAPI):
3803
4044
  response = await self.contractPrivatePostSwapApiV3SwapHisorders(self.extend(request, params))
3804
4045
  elif market['future']:
3805
4046
  request['symbol'] = market['settleId']
3806
- if stop:
4047
+ if trigger:
3807
4048
  response = await self.contractPrivatePostApiV1ContractTriggerHisorders(self.extend(request, params))
3808
4049
  elif stopLossTakeProfit:
3809
4050
  response = await self.contractPrivatePostApiV1ContractTpslHisorders(self.extend(request, params))
@@ -3959,25 +4200,27 @@ class htx(Exchange, ImplicitAPI):
3959
4200
  return self.parse_orders(orders, market, since, limit)
3960
4201
 
3961
4202
  async def fetch_closed_contract_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3962
- request = {
4203
+ request: dict = {
3963
4204
  'status': '5,6,7', # comma separated, 0 all, 3 submitted orders, 4 partially matched, 5 partially cancelled, 6 fully matched and closed, 7 canceled
3964
4205
  }
3965
4206
  return await self.fetch_contract_orders(symbol, since, limit, self.extend(request, params))
3966
4207
 
3967
4208
  async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
3968
4209
  """
3969
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
3970
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
3971
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
3972
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
3973
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
3974
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4210
+
4211
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
4212
+ https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
4213
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
4214
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
4215
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
4216
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4217
+
3975
4218
  fetches information on multiple orders made by the user
3976
4219
  :param str symbol: unified market symbol of the market orders were made in
3977
4220
  :param int [since]: the earliest time in ms to fetch orders for
3978
4221
  :param int [limit]: the maximum number of order structures to retrieve
3979
4222
  :param dict [params]: extra parameters specific to the exchange API endpoint
3980
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
4223
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
3981
4224
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
3982
4225
  :param int [params.until]: the latest time in ms to fetch entries for
3983
4226
  :param boolean [params.trailing]: *contract only* set to True if you want to fetch trailing stop orders
@@ -3999,12 +4242,14 @@ class htx(Exchange, ImplicitAPI):
3999
4242
 
4000
4243
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4001
4244
  """
4002
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
4003
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
4004
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
4005
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
4006
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
4007
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4245
+
4246
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
4247
+ https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
4248
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
4249
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
4250
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
4251
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4252
+
4008
4253
  fetches information on multiple closed orders made by the user
4009
4254
  :param str symbol: unified market symbol of the market orders were made in
4010
4255
  :param int [since]: the earliest time in ms to fetch orders for
@@ -4031,15 +4276,17 @@ class htx(Exchange, ImplicitAPI):
4031
4276
 
4032
4277
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4033
4278
  """
4034
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-open-orders
4035
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-current-unfilled-order-acquisition
4036
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-current-unfilled-order-acquisition
4279
+
4280
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-open-orders
4281
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-current-unfilled-order-acquisition
4282
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-current-unfilled-order-acquisition
4283
+
4037
4284
  fetch all unfilled currently open orders
4038
4285
  :param str symbol: unified market symbol
4039
4286
  :param int [since]: the earliest time in ms to fetch open orders for
4040
4287
  :param int [limit]: the maximum number of open order structures to retrieve
4041
4288
  :param dict [params]: extra parameters specific to the exchange API endpoint
4042
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
4289
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
4043
4290
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
4044
4291
  :param boolean [params.trailing]: *contract only* set to True if you want to fetch trailing stop orders
4045
4292
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -4048,7 +4295,7 @@ class htx(Exchange, ImplicitAPI):
4048
4295
  market = None
4049
4296
  if symbol is not None:
4050
4297
  market = self.market(symbol)
4051
- request = {}
4298
+ request: dict = {}
4052
4299
  marketType = None
4053
4300
  marketType, params = self.handle_market_type_and_params('fetchOpenOrders', market, params)
4054
4301
  response = None
@@ -4062,7 +4309,7 @@ class htx(Exchange, ImplicitAPI):
4062
4309
  await self.load_accounts()
4063
4310
  for i in range(0, len(self.accounts)):
4064
4311
  account = self.accounts[i]
4065
- if account['type'] == 'spot':
4312
+ if self.safe_string(account, 'type') == 'spot':
4066
4313
  accountId = self.safe_string(account, 'id')
4067
4314
  if accountId is not None:
4068
4315
  break
@@ -4077,16 +4324,16 @@ class htx(Exchange, ImplicitAPI):
4077
4324
  if limit is not None:
4078
4325
  request['page_size'] = limit
4079
4326
  request['contract_code'] = market['id']
4080
- stop = self.safe_value(params, 'stop')
4327
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
4081
4328
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4082
4329
  trailing = self.safe_bool(params, 'trailing', False)
4083
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
4330
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
4084
4331
  if market['linear']:
4085
4332
  marginMode = None
4086
4333
  marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
4087
4334
  marginMode = 'cross' if (marginMode is None) else marginMode
4088
4335
  if marginMode == 'isolated':
4089
- if stop:
4336
+ if trigger:
4090
4337
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerOpenorders(self.extend(request, params))
4091
4338
  elif stopLossTakeProfit:
4092
4339
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslOpenorders(self.extend(request, params))
@@ -4095,7 +4342,7 @@ class htx(Exchange, ImplicitAPI):
4095
4342
  else:
4096
4343
  response = await self.contractPrivatePostLinearSwapApiV1SwapOpenorders(self.extend(request, params))
4097
4344
  elif marginMode == 'cross':
4098
- if stop:
4345
+ if trigger:
4099
4346
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOpenorders(self.extend(request, params))
4100
4347
  elif stopLossTakeProfit:
4101
4348
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOpenorders(self.extend(request, params))
@@ -4105,7 +4352,7 @@ class htx(Exchange, ImplicitAPI):
4105
4352
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossOpenorders(self.extend(request, params))
4106
4353
  elif market['inverse']:
4107
4354
  if market['swap']:
4108
- if stop:
4355
+ if trigger:
4109
4356
  response = await self.contractPrivatePostSwapApiV1SwapTriggerOpenorders(self.extend(request, params))
4110
4357
  elif stopLossTakeProfit:
4111
4358
  response = await self.contractPrivatePostSwapApiV1SwapTpslOpenorders(self.extend(request, params))
@@ -4115,7 +4362,7 @@ class htx(Exchange, ImplicitAPI):
4115
4362
  response = await self.contractPrivatePostSwapApiV1SwapOpenorders(self.extend(request, params))
4116
4363
  elif market['future']:
4117
4364
  request['symbol'] = market['settleId']
4118
- if stop:
4365
+ if trigger:
4119
4366
  response = await self.contractPrivatePostApiV1ContractTriggerOpenorders(self.extend(request, params))
4120
4367
  elif stopLossTakeProfit:
4121
4368
  response = await self.contractPrivatePostApiV1ContractTpslOpenorders(self.extend(request, params))
@@ -4312,8 +4559,8 @@ class htx(Exchange, ImplicitAPI):
4312
4559
  orders = self.safe_value(orders, 'orders', [])
4313
4560
  return self.parse_orders(orders, market, since, limit)
4314
4561
 
4315
- def parse_order_status(self, status):
4316
- statuses = {
4562
+ def parse_order_status(self, status: Str):
4563
+ statuses: dict = {
4317
4564
  # spot
4318
4565
  'partial-filled': 'open',
4319
4566
  'partial-canceled': 'canceled',
@@ -4333,7 +4580,7 @@ class htx(Exchange, ImplicitAPI):
4333
4580
  }
4334
4581
  return self.safe_string(statuses, status, status)
4335
4582
 
4336
- def parse_order(self, order, market: Market = None) -> Order:
4583
+ def parse_order(self, order: dict, market: Market = None) -> Order:
4337
4584
  #
4338
4585
  # spot
4339
4586
  #
@@ -4710,14 +4957,10 @@ class htx(Exchange, ImplicitAPI):
4710
4957
  cost = None
4711
4958
  amount = None
4712
4959
  if (type is not None) and (type.find('market') >= 0):
4713
- # for market orders amount is in quote currency, meaning it is the cost
4714
- if side == 'sell':
4715
- cost = self.safe_string(order, 'field-cash-amount')
4716
- else:
4717
- cost = self.safe_string(order, 'amount')
4960
+ cost = self.safe_string(order, 'field-cash-amount')
4718
4961
  else:
4719
4962
  amount = self.safe_string_2(order, 'volume', 'amount')
4720
- cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo
4963
+ cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo here
4721
4964
  filled = self.safe_string_n(order, ['filled-amount', 'field-amount', 'trade_volume']) # typo in their API, filled amount
4722
4965
  price = self.safe_string_2(order, 'price', 'order_price')
4723
4966
  feeCost = self.safe_string_2(order, 'filled-fees', 'field-fees') # typo in their API, filled feeSide
@@ -4734,7 +4977,6 @@ class htx(Exchange, ImplicitAPI):
4734
4977
  'cost': feeCost,
4735
4978
  'currency': feeCurrency,
4736
4979
  }
4737
- stopPrice = self.safe_string_2(order, 'stop-price', 'trigger_price')
4738
4980
  average = self.safe_string(order, 'trade_avg_price')
4739
4981
  trades = self.safe_value(order, 'trades')
4740
4982
  reduceOnlyInteger = self.safe_integer(order, 'reduce_only')
@@ -4754,8 +4996,7 @@ class htx(Exchange, ImplicitAPI):
4754
4996
  'postOnly': None,
4755
4997
  'side': side,
4756
4998
  'price': price,
4757
- 'stopPrice': stopPrice,
4758
- 'triggerPrice': stopPrice,
4999
+ 'triggerPrice': self.safe_string_2(order, 'stop-price', 'trigger_price'),
4759
5000
  'average': average,
4760
5001
  'cost': cost,
4761
5002
  'amount': amount,
@@ -4770,7 +5011,9 @@ class htx(Exchange, ImplicitAPI):
4770
5011
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
4771
5012
  """
4772
5013
  create a market buy order by providing the symbol and cost
4773
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
5014
+
5015
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
5016
+
4774
5017
  :param str symbol: unified symbol of the market to create an order in
4775
5018
  :param float cost: how much you want to trade in units of the quote currency
4776
5019
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4806,13 +5049,13 @@ class htx(Exchange, ImplicitAPI):
4806
5049
 
4807
5050
  async def create_spot_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
4808
5051
  """
4809
- * @ignore
5052
+ @ignore
4810
5053
  helper function to build request
4811
5054
  :param str symbol: unified symbol of the market to create an order in
4812
5055
  :param str type: 'market' or 'limit'
4813
5056
  :param str side: 'buy' or 'sell'
4814
5057
  :param float amount: how much you want to trade in units of the base currency
4815
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5058
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4816
5059
  :param dict [params]: extra parameters specific to the exchange API endpoint
4817
5060
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4818
5061
  :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
@@ -4824,7 +5067,7 @@ class htx(Exchange, ImplicitAPI):
4824
5067
  marginMode = None
4825
5068
  marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
4826
5069
  accountId = await self.fetch_account_id_by_type(market['type'], marginMode, symbol)
4827
- request = {
5070
+ request: dict = {
4828
5071
  # spot -----------------------------------------------------------
4829
5072
  'account-id': accountId,
4830
5073
  'symbol': market['id'],
@@ -4839,15 +5082,15 @@ class htx(Exchange, ImplicitAPI):
4839
5082
  orderType = type.replace('buy-', '')
4840
5083
  orderType = orderType.replace('sell-', '')
4841
5084
  options = self.safe_value(self.options, market['type'], {})
4842
- stopPrice = self.safe_string_2(params, 'stopPrice', 'stop-price')
4843
- if stopPrice is None:
5085
+ triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'stop-price'])
5086
+ if triggerPrice is None:
4844
5087
  stopOrderTypes = self.safe_value(options, 'stopOrderTypes', {})
4845
5088
  if orderType in stopOrderTypes:
4846
- raise ArgumentsRequired(self.id + ' createOrder() requires a stopPrice or a stop-price parameter for a stop order')
5089
+ raise ArgumentsRequired(self.id + ' createOrder() requires a triggerPrice for a trigger order')
4847
5090
  else:
4848
5091
  defaultOperator = 'lte' if (side == 'sell') else 'gte'
4849
5092
  stopOperator = self.safe_string(params, 'operator', defaultOperator)
4850
- request['stop-price'] = self.price_to_precision(symbol, stopPrice)
5093
+ request['stop-price'] = self.price_to_precision(symbol, triggerPrice)
4851
5094
  request['operator'] = stopOperator
4852
5095
  if (orderType == 'limit') or (orderType == 'limit-fok'):
4853
5096
  orderType = 'stop-' + orderType
@@ -4905,18 +5148,18 @@ class htx(Exchange, ImplicitAPI):
4905
5148
  limitOrderTypes = self.safe_value(options, 'limitOrderTypes', {})
4906
5149
  if orderType in limitOrderTypes:
4907
5150
  request['price'] = self.price_to_precision(symbol, price)
4908
- params = self.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
5151
+ params = self.omit(params, ['triggerPrice', 'stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
4909
5152
  return self.extend(request, params)
4910
5153
 
4911
5154
  def create_contract_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
4912
5155
  """
4913
- * @ignore
5156
+ @ignore
4914
5157
  helper function to build request
4915
5158
  :param str symbol: unified symbol of the market to create an order in
4916
5159
  :param str type: 'market' or 'limit'
4917
5160
  :param str side: 'buy' or 'sell'
4918
5161
  :param float amount: how much you want to trade in units of the base currency
4919
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5162
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4920
5163
  :param dict [params]: extra parameters specific to the exchange API endpoint
4921
5164
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4922
5165
  :param float [params.trailingPercent]: *contract only* the percent to trail away from the current market price
@@ -4924,7 +5167,7 @@ class htx(Exchange, ImplicitAPI):
4924
5167
  :returns dict: request to be sent to the exchange
4925
5168
  """
4926
5169
  market = self.market(symbol)
4927
- request = {
5170
+ request: dict = {
4928
5171
  'contract_code': market['id'],
4929
5172
  'volume': self.amount_to_precision(symbol, amount),
4930
5173
  'direction': side,
@@ -4938,16 +5181,16 @@ class htx(Exchange, ImplicitAPI):
4938
5181
  type = 'fok'
4939
5182
  elif timeInForce == 'IOC':
4940
5183
  type = 'ioc'
4941
- triggerPrice = self.safe_number_2(params, 'stopPrice', 'trigger_price')
5184
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
4942
5185
  stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
4943
5186
  takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
4944
5187
  trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callback_rate')
4945
5188
  trailingTriggerPrice = self.safe_number(params, 'trailingTriggerPrice', price)
4946
5189
  isTrailingPercentOrder = trailingPercent is not None
4947
- isStop = triggerPrice is not None
5190
+ isTrigger = triggerPrice is not None
4948
5191
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
4949
5192
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
4950
- if isStop:
5193
+ if isTrigger:
4951
5194
  triggerType = self.safe_string_2(params, 'triggerType', 'trigger_type', 'le')
4952
5195
  request['trigger_type'] = triggerType
4953
5196
  request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
@@ -4976,59 +5219,70 @@ class htx(Exchange, ImplicitAPI):
4976
5219
  params = self.omit(params, ['clientOrderId'])
4977
5220
  if type == 'limit' or type == 'ioc' or type == 'fok' or type == 'post_only':
4978
5221
  request['price'] = self.price_to_precision(symbol, price)
5222
+ reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only', False)
4979
5223
  if not isStopLossTriggerOrder and not isTakeProfitTriggerOrder:
4980
- reduceOnly = self.safe_value_2(params, 'reduceOnly', 'reduce_only', False)
4981
5224
  if reduceOnly:
4982
5225
  request['reduce_only'] = 1
4983
5226
  request['lever_rate'] = self.safe_integer_n(params, ['leverRate', 'lever_rate', 'leverage'], 1)
4984
5227
  if not isTrailingPercentOrder:
4985
5228
  request['order_price_type'] = type
5229
+ hedged = self.safe_bool(params, 'hedged', False)
5230
+ if hedged:
5231
+ if reduceOnly:
5232
+ request['offset'] = 'close'
5233
+ else:
5234
+ request['offset'] = 'open'
4986
5235
  broker = self.safe_value(self.options, 'broker', {})
4987
5236
  brokerId = self.safe_string(broker, 'id')
4988
5237
  request['channel_code'] = brokerId
4989
- params = self.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
5238
+ params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice', 'hedged'])
4990
5239
  return self.extend(request, params)
4991
5240
 
4992
5241
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
4993
5242
  """
4994
5243
  create a trade order
4995
- :see: https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order # spot, margin
4996
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order # coin-m swap
4997
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order # coin-m swap trigger
4998
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order # usdt-m swap cross
4999
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order # usdt-m swap cross trigger
5000
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order # usdt-m swap isolated
5001
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order # usdt-m swap isolated trigger
5002
- :see: https://huobiapi.github.io/docs/dm/v1/en/#place-an-order # coin-m futures
5003
- :see: https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order # coin-m futures contract trigger
5244
+
5245
+ https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order # spot, margin
5246
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order # coin-m swap
5247
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order # coin-m swap trigger
5248
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order # usdt-m swap cross
5249
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order # usdt-m swap cross trigger
5250
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order # usdt-m swap isolated
5251
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order # usdt-m swap isolated trigger
5252
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-set-a-take-profit-and-stop-loss-order-for-an-existing-position
5253
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-set-a-take-profit-and-stop-loss-order-for-an-existing-position
5254
+ https://huobiapi.github.io/docs/dm/v1/en/#place-an-order # coin-m futures
5255
+ https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order # coin-m futures contract trigger
5256
+
5004
5257
  :param str symbol: unified symbol of the market to create an order in
5005
5258
  :param str type: 'market' or 'limit'
5006
5259
  :param str side: 'buy' or 'sell'
5007
5260
  :param float amount: how much you want to trade in units of the base currency
5008
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5261
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
5009
5262
  :param dict [params]: extra parameters specific to the exchange API endpoint
5010
- :param float [params.stopPrice]: the price a trigger order is triggered at
5263
+ :param float [params.triggerPrice]: the price a trigger order is triggered at
5011
5264
  :param str [params.triggerType]: *contract trigger orders only* ge: greater than or equal to, le: less than or equal to
5012
5265
  :param float [params.stopLossPrice]: *contract only* the price a stop-loss order is triggered at
5013
5266
  :param float [params.takeProfitPrice]: *contract only* the price a take-profit order is triggered at
5014
5267
  :param str [params.operator]: *spot and margin only* gte or lte, trigger price condition
5015
- :param str [params.offset]: *contract only* 'open', 'close', or 'both', required in hedge mode
5268
+ :param str [params.offset]: *contract only* 'both'(linear only), 'open', or 'close', required in hedge mode and for inverse markets
5016
5269
  :param bool [params.postOnly]: *contract only* True or False
5017
5270
  :param int [params.leverRate]: *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
5018
5271
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
5019
5272
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
5020
5273
  :param float [params.trailingPercent]: *contract only* the percent to trail away from the current market price
5021
5274
  :param float [params.trailingTriggerPrice]: *contract only* the price to trigger a trailing order, default uses the price argument
5275
+ :param bool [params.hedged]: *contract only* True for hedged mode, False for one way mode, default is False
5022
5276
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
5023
5277
  """
5024
5278
  await self.load_markets()
5025
5279
  market = self.market(symbol)
5026
- triggerPrice = self.safe_number_2(params, 'stopPrice', 'trigger_price')
5280
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
5027
5281
  stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
5028
5282
  takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
5029
5283
  trailingPercent = self.safe_number(params, 'trailingPercent')
5030
5284
  isTrailingPercentOrder = trailingPercent is not None
5031
- isStop = triggerPrice is not None
5285
+ isTrigger = triggerPrice is not None
5032
5286
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
5033
5287
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
5034
5288
  response = None
@@ -5044,7 +5298,7 @@ class htx(Exchange, ImplicitAPI):
5044
5298
  marginMode, contractRequest = self.handle_margin_mode_and_params('createOrder', contractRequest)
5045
5299
  marginMode = 'cross' if (marginMode is None) else marginMode
5046
5300
  if marginMode == 'isolated':
5047
- if isStop:
5301
+ if isTrigger:
5048
5302
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerOrder(contractRequest)
5049
5303
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5050
5304
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslOrder(contractRequest)
@@ -5053,7 +5307,7 @@ class htx(Exchange, ImplicitAPI):
5053
5307
  else:
5054
5308
  response = await self.contractPrivatePostLinearSwapApiV1SwapOrder(contractRequest)
5055
5309
  elif marginMode == 'cross':
5056
- if isStop:
5310
+ if isTrigger:
5057
5311
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(contractRequest)
5058
5312
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5059
5313
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(contractRequest)
@@ -5062,8 +5316,11 @@ class htx(Exchange, ImplicitAPI):
5062
5316
  else:
5063
5317
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossOrder(contractRequest)
5064
5318
  elif market['inverse']:
5319
+ offset = self.safe_string(params, 'offset')
5320
+ if offset is None:
5321
+ raise ArgumentsRequired(self.id + ' createOrder() requires an extra parameter params["offset"] to be set to "open" or "close" when placing orders in inverse markets')
5065
5322
  if market['swap']:
5066
- if isStop:
5323
+ if isTrigger:
5067
5324
  response = await self.contractPrivatePostSwapApiV1SwapTriggerOrder(contractRequest)
5068
5325
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5069
5326
  response = await self.contractPrivatePostSwapApiV1SwapTpslOrder(contractRequest)
@@ -5072,7 +5329,7 @@ class htx(Exchange, ImplicitAPI):
5072
5329
  else:
5073
5330
  response = await self.contractPrivatePostSwapApiV1SwapOrder(contractRequest)
5074
5331
  elif market['future']:
5075
- if isStop:
5332
+ if isTrigger:
5076
5333
  response = await self.contractPrivatePostApiV1ContractTriggerOrder(contractRequest)
5077
5334
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5078
5335
  response = await self.contractPrivatePostApiV1ContractTpslOrder(contractRequest)
@@ -5146,11 +5403,13 @@ class htx(Exchange, ImplicitAPI):
5146
5403
  async def create_orders(self, orders: List[OrderRequest], params={}):
5147
5404
  """
5148
5405
  create a list of trade orders
5149
- :see: https://huobiapi.github.io/docs/spot/v1/en/#place-a-batch-of-orders
5150
- :see: https://huobiapi.github.io/docs/dm/v1/en/#place-a-batch-of-orders
5151
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-a-batch-of-orders
5152
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-a-batch-of-orders
5153
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-a-batch-of-orders
5406
+
5407
+ https://huobiapi.github.io/docs/spot/v1/en/#place-a-batch-of-orders
5408
+ https://huobiapi.github.io/docs/dm/v1/en/#place-a-batch-of-orders
5409
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-a-batch-of-orders
5410
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-a-batch-of-orders
5411
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-a-batch-of-orders
5412
+
5154
5413
  :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
5155
5414
  :param dict [params]: extra parameters specific to the exchange API endpoint
5156
5415
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5189,7 +5448,7 @@ class htx(Exchange, ImplicitAPI):
5189
5448
  orderRequest = self.create_contract_order_request(marketId, type, side, amount, price, orderParams)
5190
5449
  orderRequest = self.omit(orderRequest, 'marginMode')
5191
5450
  ordersRequests.append(orderRequest)
5192
- request = {}
5451
+ request: dict = {}
5193
5452
  response = None
5194
5453
  if market['spot']:
5195
5454
  response = await self.privatePostOrderBatchOrders(ordersRequests)
@@ -5263,7 +5522,7 @@ class htx(Exchange, ImplicitAPI):
5263
5522
  :param str id: order id
5264
5523
  :param str symbol: unified symbol of the market the order was made in
5265
5524
  :param dict [params]: extra parameters specific to the exchange API endpoint
5266
- :param boolean [params.stop]: *contract only* if the order is a stop trigger order or not
5525
+ :param boolean [params.trigger]: *contract only* if the order is a trigger trigger order or not
5267
5526
  :param boolean [params.stopLossTakeProfit]: *contract only* if the order is a stop-loss or take-profit order
5268
5527
  :param boolean [params.trailing]: *contract only* set to True if you want to cancel a trailing order
5269
5528
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5274,7 +5533,7 @@ class htx(Exchange, ImplicitAPI):
5274
5533
  market = self.market(symbol)
5275
5534
  marketType = None
5276
5535
  marketType, params = self.handle_market_type_and_params('cancelOrder', market, params)
5277
- request = {
5536
+ request: dict = {
5278
5537
  # spot -----------------------------------------------------------
5279
5538
  # 'order-id': 'id',
5280
5539
  # 'symbol': market['id'],
@@ -5309,16 +5568,16 @@ class htx(Exchange, ImplicitAPI):
5309
5568
  request['symbol'] = market['settleId']
5310
5569
  else:
5311
5570
  request['contract_code'] = market['id']
5312
- stop = self.safe_value(params, 'stop')
5571
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5313
5572
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5314
5573
  trailing = self.safe_bool(params, 'trailing', False)
5315
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
5574
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
5316
5575
  if market['linear']:
5317
5576
  marginMode = None
5318
5577
  marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
5319
5578
  marginMode = 'cross' if (marginMode is None) else marginMode
5320
5579
  if marginMode == 'isolated':
5321
- if stop:
5580
+ if trigger:
5322
5581
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
5323
5582
  elif stopLossTakeProfit:
5324
5583
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
@@ -5327,7 +5586,7 @@ class htx(Exchange, ImplicitAPI):
5327
5586
  else:
5328
5587
  response = await self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
5329
5588
  elif marginMode == 'cross':
5330
- if stop:
5589
+ if trigger:
5331
5590
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
5332
5591
  elif stopLossTakeProfit:
5333
5592
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
@@ -5337,7 +5596,7 @@ class htx(Exchange, ImplicitAPI):
5337
5596
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
5338
5597
  elif market['inverse']:
5339
5598
  if market['swap']:
5340
- if stop:
5599
+ if trigger:
5341
5600
  response = await self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
5342
5601
  elif stopLossTakeProfit:
5343
5602
  response = await self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
@@ -5346,7 +5605,7 @@ class htx(Exchange, ImplicitAPI):
5346
5605
  else:
5347
5606
  response = await self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
5348
5607
  elif market['future']:
5349
- if stop:
5608
+ if trigger:
5350
5609
  response = await self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
5351
5610
  elif stopLossTakeProfit:
5352
5611
  response = await self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
@@ -5386,7 +5645,7 @@ class htx(Exchange, ImplicitAPI):
5386
5645
  :param str[] ids: order ids
5387
5646
  :param str symbol: unified market symbol, default is None
5388
5647
  :param dict [params]: extra parameters specific to the exchange API endpoint
5389
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
5648
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
5390
5649
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
5391
5650
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5392
5651
  """
@@ -5396,7 +5655,7 @@ class htx(Exchange, ImplicitAPI):
5396
5655
  market = self.market(symbol)
5397
5656
  marketType = None
5398
5657
  marketType, params = self.handle_market_type_and_params('cancelOrders', market, params)
5399
- request = {
5658
+ request: dict = {
5400
5659
  # spot -----------------------------------------------------------
5401
5660
  # 'order-ids': ','.join(ids), # max 50
5402
5661
  # 'client-order-ids': ','.join(ids), # max 50
@@ -5436,22 +5695,22 @@ class htx(Exchange, ImplicitAPI):
5436
5695
  request['symbol'] = market['settleId']
5437
5696
  else:
5438
5697
  request['contract_code'] = market['id']
5439
- stop = self.safe_value(params, 'stop')
5698
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5440
5699
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5441
- params = self.omit(params, ['stop', 'stopLossTakeProfit'])
5700
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trigger'])
5442
5701
  if market['linear']:
5443
5702
  marginMode = None
5444
5703
  marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
5445
5704
  marginMode = 'cross' if (marginMode is None) else marginMode
5446
5705
  if marginMode == 'isolated':
5447
- if stop:
5706
+ if trigger:
5448
5707
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
5449
5708
  elif stopLossTakeProfit:
5450
5709
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
5451
5710
  else:
5452
5711
  response = await self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
5453
5712
  elif marginMode == 'cross':
5454
- if stop:
5713
+ if trigger:
5455
5714
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
5456
5715
  elif stopLossTakeProfit:
5457
5716
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
@@ -5459,14 +5718,14 @@ class htx(Exchange, ImplicitAPI):
5459
5718
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
5460
5719
  elif market['inverse']:
5461
5720
  if market['swap']:
5462
- if stop:
5721
+ if trigger:
5463
5722
  response = await self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
5464
5723
  elif stopLossTakeProfit:
5465
5724
  response = await self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
5466
5725
  else:
5467
5726
  response = await self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
5468
5727
  elif market['future']:
5469
- if stop:
5728
+ if trigger:
5470
5729
  response = await self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
5471
5730
  elif stopLossTakeProfit:
5472
5731
  response = await self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
@@ -5525,14 +5784,69 @@ class htx(Exchange, ImplicitAPI):
5525
5784
  # "ts": 1604367997451
5526
5785
  # }
5527
5786
  #
5528
- return response
5787
+ data = self.safe_dict(response, 'data')
5788
+ return self.parse_cancel_orders(data)
5789
+
5790
+ def parse_cancel_orders(self, orders):
5791
+ #
5792
+ # {
5793
+ # "success": [
5794
+ # "5983466"
5795
+ # ],
5796
+ # "failed": [
5797
+ # {
5798
+ # "err-msg": "Incorrect order state",
5799
+ # "order-state": 7,
5800
+ # "order-id": "",
5801
+ # "err-code": "order-orderstate-error",
5802
+ # "client-order-id": "first"
5803
+ # },
5804
+ # ...
5805
+ # ]
5806
+ # }
5807
+ #
5808
+ # {
5809
+ # "errors": [
5810
+ # {
5811
+ # "order_id": "769206471845261312",
5812
+ # "err_code": 1061,
5813
+ # "err_msg": "This order doesnt exist."
5814
+ # }
5815
+ # ],
5816
+ # "successes": "1258075374411399168,1258075393254871040"
5817
+ # }
5818
+ #
5819
+ successes = self.safe_string(orders, 'successes')
5820
+ success = None
5821
+ if successes is not None:
5822
+ success = successes.split(',')
5823
+ else:
5824
+ success = self.safe_list(orders, 'success', [])
5825
+ failed = self.safe_list_2(orders, 'errors', 'failed', [])
5826
+ result = []
5827
+ for i in range(0, len(success)):
5828
+ order = success[i]
5829
+ result.append(self.safe_order({
5830
+ 'info': order,
5831
+ 'id': order,
5832
+ 'status': 'canceled',
5833
+ }))
5834
+ for i in range(0, len(failed)):
5835
+ order = failed[i]
5836
+ result.append(self.safe_order({
5837
+ 'info': order,
5838
+ 'id': self.safe_string_2(order, 'order-id', 'order_id'),
5839
+ 'status': 'failed',
5840
+ 'clientOrderId': self.safe_string(order, 'client-order-id'),
5841
+ }))
5842
+ return result
5529
5843
 
5530
5844
  async def cancel_all_orders(self, symbol: Str = None, params={}):
5531
5845
  """
5532
5846
  cancel all open orders
5533
5847
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
5534
5848
  :param dict [params]: extra parameters specific to the exchange API endpoint
5535
- :param boolean [params.stop]: *contract only* if the orders are stop trigger orders or not
5849
+ :param boolean [params.trigger]: *contract only* if the orders are trigger trigger orders or not
5536
5850
  :param boolean [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
5537
5851
  :param boolean [params.trailing]: *contract only* set to True if you want to cancel all trailing orders
5538
5852
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5543,7 +5857,7 @@ class htx(Exchange, ImplicitAPI):
5543
5857
  market = self.market(symbol)
5544
5858
  marketType = None
5545
5859
  marketType, params = self.handle_market_type_and_params('cancelAllOrders', market, params)
5546
- request = {
5860
+ request: dict = {
5547
5861
  # spot -----------------------------------------------------------
5548
5862
  # 'account-id': account['id'],
5549
5863
  # 'symbol': market['id'], # a list of comma-separated symbols, all symbols by default
@@ -5562,22 +5876,38 @@ class htx(Exchange, ImplicitAPI):
5562
5876
  if symbol is not None:
5563
5877
  request['symbol'] = market['id']
5564
5878
  response = await self.spotPrivatePostV1OrderOrdersBatchCancelOpenOrders(self.extend(request, params))
5879
+ #
5880
+ # {
5881
+ # "code": 200,
5882
+ # "data": {
5883
+ # "success-count": 2,
5884
+ # "failed-count": 0,
5885
+ # "next-id": 5454600
5886
+ # }
5887
+ # }
5888
+ #
5889
+ data = self.safe_dict(response, 'data')
5890
+ return [
5891
+ self.safe_order({
5892
+ 'info': data,
5893
+ }),
5894
+ ]
5565
5895
  else:
5566
5896
  if symbol is None:
5567
5897
  raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
5568
5898
  if market['future']:
5569
5899
  request['symbol'] = market['settleId']
5570
5900
  request['contract_code'] = market['id']
5571
- stop = self.safe_value(params, 'stop')
5901
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5572
5902
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5573
5903
  trailing = self.safe_bool(params, 'trailing', False)
5574
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
5904
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
5575
5905
  if market['linear']:
5576
5906
  marginMode = None
5577
5907
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
5578
5908
  marginMode = 'cross' if (marginMode is None) else marginMode
5579
5909
  if marginMode == 'isolated':
5580
- if stop:
5910
+ if trigger:
5581
5911
  response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancelall(self.extend(request, params))
5582
5912
  elif stopLossTakeProfit:
5583
5913
  response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancelall(self.extend(request, params))
@@ -5586,7 +5916,7 @@ class htx(Exchange, ImplicitAPI):
5586
5916
  else:
5587
5917
  response = await self.contractPrivatePostLinearSwapApiV1SwapCancelall(self.extend(request, params))
5588
5918
  elif marginMode == 'cross':
5589
- if stop:
5919
+ if trigger:
5590
5920
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancelall(self.extend(request, params))
5591
5921
  elif stopLossTakeProfit:
5592
5922
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancelall(self.extend(request, params))
@@ -5596,7 +5926,7 @@ class htx(Exchange, ImplicitAPI):
5596
5926
  response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancelall(self.extend(request, params))
5597
5927
  elif market['inverse']:
5598
5928
  if market['swap']:
5599
- if stop:
5929
+ if trigger:
5600
5930
  response = await self.contractPrivatePostSwapApiV1SwapTriggerCancelall(self.extend(request, params))
5601
5931
  elif stopLossTakeProfit:
5602
5932
  response = await self.contractPrivatePostSwapApiV1SwapTpslCancelall(self.extend(request, params))
@@ -5605,7 +5935,7 @@ class htx(Exchange, ImplicitAPI):
5605
5935
  else:
5606
5936
  response = await self.contractPrivatePostSwapApiV1SwapCancelall(self.extend(request, params))
5607
5937
  elif market['future']:
5608
- if stop:
5938
+ if trigger:
5609
5939
  response = await self.contractPrivatePostApiV1ContractTriggerCancelall(self.extend(request, params))
5610
5940
  elif stopLossTakeProfit:
5611
5941
  response = await self.contractPrivatePostApiV1ContractTpslCancelall(self.extend(request, params))
@@ -5615,29 +5945,44 @@ class htx(Exchange, ImplicitAPI):
5615
5945
  response = await self.contractPrivatePostApiV1ContractCancelall(self.extend(request, params))
5616
5946
  else:
5617
5947
  raise NotSupported(self.id + ' cancelAllOrders() does not support ' + marketType + ' markets')
5618
- #
5619
- # spot
5948
+ #
5949
+ # {
5950
+ # "status": "ok",
5951
+ # "data": {
5952
+ # "errors": [],
5953
+ # "successes": "1104754904426696704"
5954
+ # },
5955
+ # "ts": "1683435723755"
5956
+ # }
5957
+ #
5958
+ data = self.safe_dict(response, 'data')
5959
+ return self.parse_cancel_orders(data)
5960
+
5961
+ async def cancel_all_orders_after(self, timeout: Int, params={}):
5962
+ """
5963
+ dead man's switch, cancel all orders after the given timeout
5964
+
5965
+ https://huobiapi.github.io/docs/spot/v1/en/#dead-man-s-switch
5966
+
5967
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
5968
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5969
+ :returns dict: the api result
5970
+ """
5971
+ await self.load_markets()
5972
+ request: dict = {
5973
+ 'timeout': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
5974
+ }
5975
+ response = await self.v2PrivatePostAlgoOrdersCancelAllAfter(self.extend(request, params))
5620
5976
  #
5621
5977
  # {
5622
5978
  # "code": 200,
5979
+ # "message": "success",
5623
5980
  # "data": {
5624
- # "success-count": 2,
5625
- # "failed-count": 0,
5626
- # "next-id": 5454600
5981
+ # "currentTime": 1630491627230,
5982
+ # "triggerTime": 1630491637230
5627
5983
  # }
5628
5984
  # }
5629
5985
  #
5630
- # future and swap
5631
- #
5632
- # {
5633
- # "status": "ok",
5634
- # "data": {
5635
- # "errors": [],
5636
- # "successes": "1104754904426696704"
5637
- # },
5638
- # "ts": "1683435723755"
5639
- # }
5640
- #
5641
5986
  return response
5642
5987
 
5643
5988
  def parse_deposit_address(self, depositAddress, currency: Currency = None):
@@ -5666,8 +6011,11 @@ class htx(Exchange, ImplicitAPI):
5666
6011
  'info': depositAddress,
5667
6012
  }
5668
6013
 
5669
- async def fetch_deposit_addresses_by_network(self, code: str, params={}):
6014
+ async def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
5670
6015
  """
6016
+
6017
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec50029-7773-11ed-9966-0242ac110003
6018
+
5671
6019
  fetch a dictionary of addresses for a currency, indexed by network
5672
6020
  :param str code: unified currency code of the currency for the deposit address
5673
6021
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5675,7 +6023,7 @@ class htx(Exchange, ImplicitAPI):
5675
6023
  """
5676
6024
  await self.load_markets()
5677
6025
  currency = self.currency(code)
5678
- request = {
6026
+ request: dict = {
5679
6027
  'currency': currency['id'],
5680
6028
  }
5681
6029
  response = await self.spotPrivateGetV2AccountDepositAddress(self.extend(request, params))
@@ -5696,9 +6044,12 @@ class htx(Exchange, ImplicitAPI):
5696
6044
  parsed = self.parse_deposit_addresses(data, [currency['code']], False)
5697
6045
  return self.index_by(parsed, 'network')
5698
6046
 
5699
- async def fetch_deposit_address(self, code: str, params={}):
6047
+ async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
5700
6048
  """
5701
6049
  fetch the deposit address for a currency associated with self account
6050
+
6051
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec50029-7773-11ed-9966-0242ac110003
6052
+
5702
6053
  :param str code: unified currency code
5703
6054
  :param dict [params]: extra parameters specific to the exchange API endpoint
5704
6055
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -5713,7 +6064,7 @@ class htx(Exchange, ImplicitAPI):
5713
6064
  async def fetch_withdraw_addresses(self, code: str, note=None, networkCode=None, params={}):
5714
6065
  await self.load_markets()
5715
6066
  currency = self.currency(code)
5716
- request = {
6067
+ request: dict = {
5717
6068
  'currency': currency['id'],
5718
6069
  }
5719
6070
  response = await self.spotPrivateGetV2AccountWithdrawAddress(self.extend(request, params))
@@ -5744,6 +6095,9 @@ class htx(Exchange, ImplicitAPI):
5744
6095
 
5745
6096
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
5746
6097
  """
6098
+
6099
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4f050-7773-11ed-9966-0242ac110003
6100
+
5747
6101
  fetch all deposits made to an account
5748
6102
  :param str code: unified currency code
5749
6103
  :param int [since]: the earliest time in ms to fetch deposits for
@@ -5757,7 +6111,7 @@ class htx(Exchange, ImplicitAPI):
5757
6111
  currency = None
5758
6112
  if code is not None:
5759
6113
  currency = self.currency(code)
5760
- request = {
6114
+ request: dict = {
5761
6115
  'type': 'deposit',
5762
6116
  'direct': 'next',
5763
6117
  'from': 0, # From 'id' ... if you want to get results after a particular transaction id, pass the id in params.from
@@ -5798,6 +6152,9 @@ class htx(Exchange, ImplicitAPI):
5798
6152
  async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
5799
6153
  """
5800
6154
  fetch all withdrawals made from an account
6155
+
6156
+ https://huobiapi.github.io/docs/spot/v1/en/#search-for-existed-withdraws-and-deposits
6157
+
5801
6158
  :param str code: unified currency code
5802
6159
  :param int [since]: the earliest time in ms to fetch withdrawals for
5803
6160
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -5810,7 +6167,7 @@ class htx(Exchange, ImplicitAPI):
5810
6167
  currency = None
5811
6168
  if code is not None:
5812
6169
  currency = self.currency(code)
5813
- request = {
6170
+ request: dict = {
5814
6171
  'type': 'withdraw',
5815
6172
  'direct': 'next',
5816
6173
  'from': 0, # From 'id' ... if you want to get results after a particular transaction id, pass the id in params.from
@@ -5846,7 +6203,7 @@ class htx(Exchange, ImplicitAPI):
5846
6203
  #
5847
6204
  return self.parse_transactions(response['data'], currency, since, limit)
5848
6205
 
5849
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
6206
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
5850
6207
  #
5851
6208
  # fetchDeposits
5852
6209
  #
@@ -5938,8 +6295,8 @@ class htx(Exchange, ImplicitAPI):
5938
6295
  },
5939
6296
  }
5940
6297
 
5941
- def parse_transaction_status(self, status):
5942
- statuses = {
6298
+ def parse_transaction_status(self, status: Str):
6299
+ statuses: dict = {
5943
6300
  # deposit statuses
5944
6301
  'unknown': 'failed',
5945
6302
  'confirming': 'pending',
@@ -5961,8 +6318,11 @@ class htx(Exchange, ImplicitAPI):
5961
6318
  }
5962
6319
  return self.safe_string(statuses, status, status)
5963
6320
 
5964
- async def withdraw(self, code: str, amount: float, address, tag=None, params={}):
6321
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
5965
6322
  """
6323
+
6324
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4cc41-7773-11ed-9966-0242ac110003
6325
+
5966
6326
  make a withdrawal
5967
6327
  :param str code: unified currency code
5968
6328
  :param float amount: the amount to withdraw
@@ -5975,7 +6335,7 @@ class htx(Exchange, ImplicitAPI):
5975
6335
  await self.load_markets()
5976
6336
  self.check_address(address)
5977
6337
  currency = self.currency(code)
5978
- request = {
6338
+ request: dict = {
5979
6339
  'address': address, # only supports existing addresses in your withdraw address list
5980
6340
  'currency': currency['id'].lower(),
5981
6341
  }
@@ -6014,7 +6374,7 @@ class htx(Exchange, ImplicitAPI):
6014
6374
  #
6015
6375
  return self.parse_transaction(response, currency)
6016
6376
 
6017
- def parse_transfer(self, transfer, currency: Currency = None):
6377
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
6018
6378
  #
6019
6379
  # transfer
6020
6380
  #
@@ -6040,13 +6400,15 @@ class htx(Exchange, ImplicitAPI):
6040
6400
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
6041
6401
  """
6042
6402
  transfer currency internally between wallets on the same account
6043
- :see: https://huobiapi.github.io/docs/dm/v1/en/#transfer-margin-between-spot-account-and-future-account
6044
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-fund-between-spot-account-and-future-contract-account
6045
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-transfer-margin-between-spot-account-and-usdt-margined-contracts-account
6046
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-cross-margin-account-cross
6047
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-isolated-margin-account-isolated
6048
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-cross-margin-account-to-spot-trading-account-cross
6049
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-isolated-margin-account-to-spot-trading-account-isolated
6403
+
6404
+ https://huobiapi.github.io/docs/dm/v1/en/#transfer-margin-between-spot-account-and-future-account
6405
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-fund-between-spot-account-and-future-contract-account
6406
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-transfer-margin-between-spot-account-and-usdt-margined-contracts-account
6407
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-cross-margin-account-cross
6408
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-isolated-margin-account-isolated
6409
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-cross-margin-account-to-spot-trading-account-cross
6410
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-isolated-margin-account-to-spot-trading-account-isolated
6411
+
6050
6412
  :param str code: unified currency code
6051
6413
  :param float amount: amount to transfer
6052
6414
  :param str fromAccount: account to transfer from 'spot', 'future', 'swap'
@@ -6058,7 +6420,7 @@ class htx(Exchange, ImplicitAPI):
6058
6420
  """
6059
6421
  await self.load_markets()
6060
6422
  currency = self.currency(code)
6061
- request = {
6423
+ request: dict = {
6062
6424
  'currency': currency['id'],
6063
6425
  'amount': float(self.currency_to_precision(code, amount)),
6064
6426
  }
@@ -6119,9 +6481,12 @@ class htx(Exchange, ImplicitAPI):
6119
6481
  #
6120
6482
  return self.parse_transfer(response, currency)
6121
6483
 
6122
- async def fetch_isolated_borrow_rates(self, params={}):
6484
+ async def fetch_isolated_borrow_rates(self, params={}) -> IsolatedBorrowRates:
6123
6485
  """
6124
6486
  fetch the borrow interest rates of all currencies
6487
+
6488
+ https://huobiapi.github.io/docs/spot/v1/en/#get-loan-interest-rate-and-quota-isolated
6489
+
6125
6490
  :param dict [params]: extra parameters specific to the exchange API endpoint
6126
6491
  :returns dict: a list of `isolated borrow rate structures <https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure>`
6127
6492
  """
@@ -6157,12 +6522,9 @@ class htx(Exchange, ImplicitAPI):
6157
6522
  # }
6158
6523
  #
6159
6524
  data = self.safe_value(response, 'data', [])
6160
- rates = []
6161
- for i in range(0, len(data)):
6162
- rates.append(self.parse_isolated_borrow_rate(data[i]))
6163
- return rates
6525
+ return self.parse_isolated_borrow_rates(data)
6164
6526
 
6165
- def parse_isolated_borrow_rate(self, info, market: Market = None):
6527
+ def parse_isolated_borrow_rate(self, info: dict, market: Market = None) -> IsolatedBorrowRate:
6166
6528
  #
6167
6529
  # {
6168
6530
  # "symbol": "1inchusdt",
@@ -6207,8 +6569,10 @@ class htx(Exchange, ImplicitAPI):
6207
6569
 
6208
6570
  async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6209
6571
  """
6210
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-funding-rate
6211
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-funding-rate
6572
+
6573
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-funding-rate
6574
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-funding-rate
6575
+
6212
6576
  fetches historical funding rate prices
6213
6577
  :param str symbol: unified symbol of the market to fetch the funding rate history for
6214
6578
  :param int [since]: not used by huobi, but filtered internally by ccxt
@@ -6225,7 +6589,7 @@ class htx(Exchange, ImplicitAPI):
6225
6589
  return await self.fetch_paginated_call_cursor('fetchFundingRateHistory', symbol, since, limit, params, 'page_index', 'current_page', 1, 50)
6226
6590
  await self.load_markets()
6227
6591
  market = self.market(symbol)
6228
- request = {
6592
+ request: dict = {
6229
6593
  'contract_code': market['id'],
6230
6594
  }
6231
6595
  response = None
@@ -6277,7 +6641,7 @@ class htx(Exchange, ImplicitAPI):
6277
6641
  sorted = self.sort_by(rates, 'timestamp')
6278
6642
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
6279
6643
 
6280
- def parse_funding_rate(self, contract, market: Market = None):
6644
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
6281
6645
  #
6282
6646
  # {
6283
6647
  # "status": "ok",
@@ -6296,6 +6660,9 @@ class htx(Exchange, ImplicitAPI):
6296
6660
  nextFundingRate = self.safe_number(contract, 'estimated_rate')
6297
6661
  fundingTimestamp = self.safe_integer(contract, 'funding_time')
6298
6662
  nextFundingTimestamp = self.safe_integer(contract, 'next_funding_time')
6663
+ fundingTimeString = self.safe_string(contract, 'funding_time')
6664
+ nextFundingTimeString = self.safe_string(contract, 'next_funding_time')
6665
+ millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
6299
6666
  marketId = self.safe_string(contract, 'contract_code')
6300
6667
  symbol = self.safe_symbol(marketId, market)
6301
6668
  return {
@@ -6316,18 +6683,33 @@ class htx(Exchange, ImplicitAPI):
6316
6683
  'previousFundingRate': None,
6317
6684
  'previousFundingTimestamp': None,
6318
6685
  'previousFundingDatetime': None,
6686
+ 'interval': self.parse_funding_interval(millisecondsInterval),
6319
6687
  }
6320
6688
 
6321
- async def fetch_funding_rate(self, symbol: str, params={}):
6689
+ def parse_funding_interval(self, interval):
6690
+ intervals: dict = {
6691
+ '3600000': '1h',
6692
+ '14400000': '4h',
6693
+ '28800000': '8h',
6694
+ '57600000': '16h',
6695
+ '86400000': '24h',
6696
+ }
6697
+ return self.safe_string(intervals, interval, interval)
6698
+
6699
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
6322
6700
  """
6323
6701
  fetch the current funding rate
6702
+
6703
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-funding-rate
6704
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-funding-rate
6705
+
6324
6706
  :param str symbol: unified market symbol
6325
6707
  :param dict [params]: extra parameters specific to the exchange API endpoint
6326
6708
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
6327
6709
  """
6328
6710
  await self.load_markets()
6329
6711
  market = self.market(symbol)
6330
- request = {
6712
+ request: dict = {
6331
6713
  'contract_code': market['id'],
6332
6714
  }
6333
6715
  response = None
@@ -6355,12 +6737,16 @@ class htx(Exchange, ImplicitAPI):
6355
6737
  result = self.safe_value(response, 'data', {})
6356
6738
  return self.parse_funding_rate(result, market)
6357
6739
 
6358
- async def fetch_funding_rates(self, symbols: Strings = None, params={}):
6740
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6359
6741
  """
6360
6742
  fetch the funding rate for multiple markets
6743
+
6744
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-funding-rate
6745
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-funding-rate
6746
+
6361
6747
  :param str[]|None symbols: list of unified market symbols
6362
6748
  :param dict [params]: extra parameters specific to the exchange API endpoint
6363
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
6749
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
6364
6750
  """
6365
6751
  await self.load_markets()
6366
6752
  symbols = self.market_symbols(symbols)
@@ -6368,7 +6754,7 @@ class htx(Exchange, ImplicitAPI):
6368
6754
  defaultSubType = self.safe_string(self.options, 'defaultSubType', 'inverse')
6369
6755
  subType = self.safe_string(options, 'subType', defaultSubType)
6370
6756
  subType = self.safe_string(params, 'subType', subType)
6371
- request = {
6757
+ request: dict = {
6372
6758
  # 'contract_code': market['id'],
6373
6759
  }
6374
6760
  params = self.omit(params, 'subType')
@@ -6398,12 +6784,15 @@ class htx(Exchange, ImplicitAPI):
6398
6784
  # }
6399
6785
  #
6400
6786
  data = self.safe_value(response, 'data', [])
6401
- result = self.parse_funding_rates(data)
6402
- return self.filter_by_array(result, 'symbol', symbols)
6787
+ return self.parse_funding_rates(data, symbols)
6403
6788
 
6404
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6789
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6405
6790
  """
6406
6791
  fetch the interest owed by the user for borrowing currency for margin trading
6792
+
6793
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-cross
6794
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-isolated
6795
+
6407
6796
  :param str code: unified currency code
6408
6797
  :param str symbol: unified market symbol when fetch interest in isolated markets
6409
6798
  :param int [since]: the earliest time in ms to fetch borrrow interest for
@@ -6415,7 +6804,7 @@ class htx(Exchange, ImplicitAPI):
6415
6804
  marginMode = None
6416
6805
  marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params)
6417
6806
  marginMode = 'cross' if (marginMode is None) else marginMode
6418
- request = {}
6807
+ request: dict = {}
6419
6808
  if since is not None:
6420
6809
  request['start-date'] = self.yyyymmdd(since)
6421
6810
  if limit is not None:
@@ -6458,7 +6847,7 @@ class htx(Exchange, ImplicitAPI):
6458
6847
  interest = self.parse_borrow_interests(data, market)
6459
6848
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6460
6849
 
6461
- def parse_borrow_interest(self, info, market: Market = None):
6850
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6462
6851
  # isolated
6463
6852
  # {
6464
6853
  # "interest-rate":"0.000040830000000000",
@@ -6506,18 +6895,20 @@ class htx(Exchange, ImplicitAPI):
6506
6895
  symbol = self.safe_string(market, 'symbol')
6507
6896
  timestamp = self.safe_integer(info, 'accrued-at')
6508
6897
  return {
6509
- 'account': symbol if (marginMode == 'isolated') else 'cross', # deprecated
6898
+ 'info': info,
6510
6899
  'symbol': symbol,
6511
- 'marginMode': marginMode,
6512
6900
  'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6513
6901
  'interest': self.safe_number(info, 'interest-amount'),
6514
6902
  'interestRate': self.safe_number(info, 'interest-rate'),
6515
6903
  'amountBorrowed': self.safe_number(info, 'loan-amount'),
6904
+ 'marginMode': marginMode,
6516
6905
  'timestamp': timestamp, # Interest accrued time
6517
6906
  'datetime': self.iso8601(timestamp),
6518
- 'info': info,
6519
6907
  }
6520
6908
 
6909
+ def nonce(self):
6910
+ return self.milliseconds() - self.options['timeDifference']
6911
+
6521
6912
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
6522
6913
  url = '/'
6523
6914
  query = self.omit(params, self.extract_params(path))
@@ -6530,8 +6921,8 @@ class htx(Exchange, ImplicitAPI):
6530
6921
  url += '/' + self.implode_params(path, params)
6531
6922
  if api == 'private' or api == 'v2Private':
6532
6923
  self.check_required_credentials()
6533
- timestamp = self.ymdhms(self.milliseconds(), 'T')
6534
- request = {
6924
+ timestamp = self.ymdhms(self.nonce(), 'T')
6925
+ request: dict = {
6535
6926
  'SignatureMethod': 'HmacSHA256',
6536
6927
  'SignatureVersion': '2',
6537
6928
  'AccessKeyId': self.apiKey,
@@ -6594,8 +6985,8 @@ class htx(Exchange, ImplicitAPI):
6594
6985
  clientOrderId = self.safe_string(params, 'client-order-id')
6595
6986
  if clientOrderId is None:
6596
6987
  params['client-order-id'] = id + self.uuid()
6597
- timestamp = self.ymdhms(self.milliseconds(), 'T')
6598
- request = {
6988
+ timestamp = self.ymdhms(self.nonce(), 'T')
6989
+ request: dict = {
6599
6990
  'SignatureMethod': 'HmacSHA256',
6600
6991
  'SignatureVersion': '2',
6601
6992
  'AccessKeyId': self.apiKey,
@@ -6626,7 +7017,7 @@ class htx(Exchange, ImplicitAPI):
6626
7017
  }) + url
6627
7018
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
6628
7019
 
6629
- def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
7020
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
6630
7021
  if response is None:
6631
7022
  return None # fallback to default error handler
6632
7023
  if 'status' in response:
@@ -6652,9 +7043,11 @@ class htx(Exchange, ImplicitAPI):
6652
7043
  async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6653
7044
  """
6654
7045
  fetch the history of funding payments paid and received on self account
6655
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-account-financial-records-via-multiple-fields-new # linear swaps
6656
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-financial-records-via-multiple-fields-new # coin-m futures
6657
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-financial-records-via-multiple-fields-new # coin-m swaps
7046
+
7047
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-account-financial-records-via-multiple-fields-new # linear swaps
7048
+ https://huobiapi.github.io/docs/dm/v1/en/#query-financial-records-via-multiple-fields-new # coin-m futures
7049
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-financial-records-via-multiple-fields-new # coin-m swaps
7050
+
6658
7051
  :param str symbol: unified market symbol
6659
7052
  :param int [since]: the earliest time in ms to fetch funding history for
6660
7053
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -6664,7 +7057,7 @@ class htx(Exchange, ImplicitAPI):
6664
7057
  await self.load_markets()
6665
7058
  market = self.market(symbol)
6666
7059
  marketType, query = self.handle_market_type_and_params('fetchFundingHistory', market, params)
6667
- request = {
7060
+ request: dict = {
6668
7061
  'type': '30,31',
6669
7062
  }
6670
7063
  if since is not None:
@@ -6728,12 +7121,18 @@ class htx(Exchange, ImplicitAPI):
6728
7121
  else:
6729
7122
  request['symbol'] = market['id']
6730
7123
  response = await self.contractPrivatePostApiV3ContractFinancialRecordExact(self.extend(request, query))
6731
- data = self.safe_value(response, 'data', [])
7124
+ data = self.safe_list(response, 'data', [])
6732
7125
  return self.parse_incomes(data, market, since, limit)
6733
7126
 
6734
7127
  async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
6735
7128
  """
6736
7129
  set the level of leverage for a market
7130
+
7131
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-leverage
7132
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-leverage
7133
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#switch-leverage
7134
+ https://huobiapi.github.io/docs/dm/v1/en/#switch-leverage # Coin-m futures
7135
+
6737
7136
  :param float leverage: the rate of leverage
6738
7137
  :param str symbol: unified market symbol
6739
7138
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6744,7 +7143,7 @@ class htx(Exchange, ImplicitAPI):
6744
7143
  await self.load_markets()
6745
7144
  market = self.market(symbol)
6746
7145
  marketType, query = self.handle_market_type_and_params('setLeverage', market, params)
6747
- request = {
7146
+ request: dict = {
6748
7147
  'lever_rate': leverage,
6749
7148
  }
6750
7149
  if marketType == 'future' and market['inverse']:
@@ -6826,7 +7225,7 @@ class htx(Exchange, ImplicitAPI):
6826
7225
  'amount': amount,
6827
7226
  }
6828
7227
 
6829
- def parse_position(self, position, market: Market = None):
7228
+ def parse_position(self, position: dict, market: Market = None):
6830
7229
  #
6831
7230
  # {
6832
7231
  # "symbol": "BTC",
@@ -6895,7 +7294,7 @@ class htx(Exchange, ImplicitAPI):
6895
7294
  'entryPrice': entryPrice,
6896
7295
  'collateral': self.parse_number(collateral),
6897
7296
  'side': side,
6898
- 'unrealizedProfit': unrealizedProfit,
7297
+ 'unrealizedPnl': unrealizedProfit,
6899
7298
  'leverage': self.parse_number(leverage),
6900
7299
  'percentage': self.parse_number(percentage),
6901
7300
  'marginMode': marginMode,
@@ -6919,16 +7318,27 @@ class htx(Exchange, ImplicitAPI):
6919
7318
  async def fetch_positions(self, symbols: Strings = None, params={}):
6920
7319
  """
6921
7320
  fetch all open positions
6922
- :param str[]|None symbols: list of unified market symbols
7321
+
7322
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-position-information
7323
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-position-information
7324
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-position-information
7325
+ https://huobiapi.github.io/docs/dm/v1/en/#query-user-s-position-information
7326
+
7327
+ :param str[] [symbols]: list of unified market symbols
6923
7328
  :param dict [params]: extra parameters specific to the exchange API endpoint
7329
+ :param str [params.subType]: 'linear' or 'inverse'
7330
+ :param str [params.type]: *inverse only* 'future', or 'swap'
7331
+ :param str [params.marginMode]: *linear only* 'cross' or 'isolated'
6924
7332
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
6925
7333
  """
6926
7334
  await self.load_markets()
6927
7335
  symbols = self.market_symbols(symbols)
6928
7336
  market = None
6929
7337
  if symbols is not None:
6930
- first = self.safe_string(symbols, 0)
6931
- market = self.market(first)
7338
+ symbolsLength = len(symbols)
7339
+ if symbolsLength > 0:
7340
+ first = self.safe_string(symbols, 0)
7341
+ market = self.market(first)
6932
7342
  marginMode = None
6933
7343
  marginMode, params = self.handle_margin_mode_and_params('fetchPositions', params, 'cross')
6934
7344
  subType = None
@@ -7044,6 +7454,12 @@ class htx(Exchange, ImplicitAPI):
7044
7454
  async def fetch_position(self, symbol: str, params={}):
7045
7455
  """
7046
7456
  fetch data on a single open contract trade position
7457
+
7458
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-assets-and-positions
7459
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-assets-and-positions
7460
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-assets-and-positions
7461
+ https://huobiapi.github.io/docs/dm/v1/en/#query-assets-and-positions
7462
+
7047
7463
  :param str symbol: unified market symbol of the market the position is held in, default is None
7048
7464
  :param dict [params]: extra parameters specific to the exchange API endpoint
7049
7465
  :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
@@ -7054,7 +7470,7 @@ class htx(Exchange, ImplicitAPI):
7054
7470
  marginMode, params = self.handle_margin_mode_and_params('fetchPosition', params)
7055
7471
  marginMode = 'cross' if (marginMode is None) else marginMode
7056
7472
  marketType, query = self.handle_market_type_and_params('fetchPosition', market, params)
7057
- request = {}
7473
+ request: dict = {}
7058
7474
  if market['future'] and market['inverse']:
7059
7475
  request['symbol'] = market['settleId']
7060
7476
  else:
@@ -7286,7 +7702,7 @@ class htx(Exchange, ImplicitAPI):
7286
7702
  return parsed
7287
7703
 
7288
7704
  def parse_ledger_entry_type(self, type):
7289
- types = {
7705
+ types: dict = {
7290
7706
  'trade': 'trade',
7291
7707
  'etf': 'trade',
7292
7708
  'transact-fee': 'fee',
@@ -7304,7 +7720,7 @@ class htx(Exchange, ImplicitAPI):
7304
7720
  }
7305
7721
  return self.safe_string(types, type, type)
7306
7722
 
7307
- def parse_ledger_entry(self, item, currency: Currency = None):
7723
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
7308
7724
  #
7309
7725
  # {
7310
7726
  # "accountId": 10000001,
@@ -7318,45 +7734,44 @@ class htx(Exchange, ImplicitAPI):
7318
7734
  # "transferee": 13496526
7319
7735
  # }
7320
7736
  #
7321
- id = self.safe_string(item, 'transactId')
7322
7737
  currencyId = self.safe_string(item, 'currency')
7323
7738
  code = self.safe_currency_code(currencyId, currency)
7324
- amount = self.safe_number(item, 'transactAmt')
7739
+ currency = self.safe_currency(currencyId, currency)
7740
+ id = self.safe_string(item, 'transactId')
7325
7741
  transferType = self.safe_string(item, 'transferType')
7326
- type = self.parse_ledger_entry_type(transferType)
7327
- direction = self.safe_string(item, 'direction')
7328
7742
  timestamp = self.safe_integer(item, 'transactTime')
7329
- datetime = self.iso8601(timestamp)
7330
7743
  account = self.safe_string(item, 'accountId')
7331
- return {
7744
+ return self.safe_ledger_entry({
7745
+ 'info': item,
7332
7746
  'id': id,
7333
- 'direction': direction,
7747
+ 'direction': self.safe_string(item, 'direction'),
7334
7748
  'account': account,
7335
7749
  'referenceId': id,
7336
7750
  'referenceAccount': account,
7337
- 'type': type,
7751
+ 'type': self.parse_ledger_entry_type(transferType),
7338
7752
  'currency': code,
7339
- 'amount': amount,
7753
+ 'amount': self.safe_number(item, 'transactAmt'),
7340
7754
  'timestamp': timestamp,
7341
- 'datetime': datetime,
7755
+ 'datetime': self.iso8601(timestamp),
7342
7756
  'before': None,
7343
7757
  'after': None,
7344
7758
  'status': None,
7345
7759
  'fee': None,
7346
- 'info': item,
7347
- }
7760
+ }, currency)
7348
7761
 
7349
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
7762
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
7350
7763
  """
7351
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-account-history
7352
- fetch the history of changes, actions done by the user or operations that altered balance of the user
7353
- :param str code: unified currency code, default is None
7764
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
7765
+
7766
+ https://huobiapi.github.io/docs/spot/v1/en/#get-account-history
7767
+
7768
+ :param str [code]: unified currency code, default is None
7354
7769
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
7355
- :param int [limit]: max number of ledger entrys to return, default is None
7770
+ :param int [limit]: max number of ledger entries to return, default is None
7356
7771
  :param dict [params]: extra parameters specific to the exchange API endpoint
7357
7772
  :param int [params.until]: the latest time in ms to fetch entries for
7358
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
7359
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
7773
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
7774
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
7360
7775
  """
7361
7776
  await self.load_markets()
7362
7777
  paginate = False
@@ -7364,7 +7779,7 @@ class htx(Exchange, ImplicitAPI):
7364
7779
  if paginate:
7365
7780
  return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params, 500)
7366
7781
  accountId = await self.fetch_account_id_by_type('spot', None, None, params)
7367
- request = {
7782
+ request: dict = {
7368
7783
  'accountId': accountId,
7369
7784
  # 'currency': code,
7370
7785
  # 'transactTypes': 'all', # default all
@@ -7419,7 +7834,7 @@ class htx(Exchange, ImplicitAPI):
7419
7834
  data = self.safe_value(response, 'data', [])
7420
7835
  return self.parse_ledger(data, currency, since, limit)
7421
7836
 
7422
- async def fetch_leverage_tiers(self, symbols: Strings = None, params={}):
7837
+ async def fetch_leverage_tiers(self, symbols: Strings = None, params={}) -> LeverageTiers:
7423
7838
  """
7424
7839
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
7425
7840
  :param str[]|None symbols: list of unified market symbols
@@ -7457,92 +7872,41 @@ class htx(Exchange, ImplicitAPI):
7457
7872
  # ]
7458
7873
  # }
7459
7874
  #
7460
- data = self.safe_value(response, 'data')
7875
+ data = self.safe_list(response, 'data', [])
7461
7876
  return self.parse_leverage_tiers(data, symbols, 'contract_code')
7462
7877
 
7463
- async def fetch_market_leverage_tiers(self, symbol: str, params={}):
7464
- """
7465
- retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
7466
- :param str symbol: unified market symbol
7467
- :param dict [params]: extra parameters specific to the exchange API endpoint
7468
- :returns dict: a `leverage tiers structure <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`
7469
- """
7470
- await self.load_markets()
7471
- request = {}
7472
- if symbol is not None:
7473
- market = self.market(symbol)
7474
- if not market['contract']:
7475
- raise BadRequest(self.id + ' fetchMarketLeverageTiers() symbol supports contract markets only')
7476
- request['contract_code'] = market['id']
7477
- response = await self.contractPublicGetLinearSwapApiV1SwapAdjustfactor(self.extend(request, params))
7478
- #
7479
- # {
7480
- # "status": "ok",
7481
- # "data": [
7482
- # {
7483
- # "symbol": "MANA",
7484
- # "contract_code": "MANA-USDT",
7485
- # "margin_mode": "isolated",
7486
- # "trade_partition": "USDT",
7487
- # "list": [
7488
- # {
7489
- # "lever_rate": 75,
7490
- # "ladders": [
7491
- # {
7492
- # "ladder": 0,
7493
- # "min_size": 0,
7494
- # "max_size": 999,
7495
- # "adjust_factor": 0.7
7496
- # },
7497
- # ...
7498
- # ]
7499
- # }
7500
- # ...
7501
- # ]
7502
- # },
7503
- # ...
7504
- # ]
7505
- # }
7506
- #
7507
- data = self.safe_value(response, 'data')
7508
- tiers = self.parse_leverage_tiers(data, [symbol], 'contract_code')
7509
- return self.safe_value(tiers, symbol)
7510
-
7511
- def parse_leverage_tiers(self, response, symbols: Strings = None, marketIdKey=None):
7512
- result = {}
7513
- for i in range(0, len(response)):
7514
- item = response[i]
7515
- list = self.safe_value(item, 'list', [])
7516
- tiers = []
7517
- currency = self.safe_string(item, 'trade_partition')
7518
- id = self.safe_string(item, marketIdKey)
7519
- symbol = self.safe_symbol(id)
7520
- if self.in_array(symbol, symbols):
7521
- for j in range(0, len(list)):
7522
- obj = list[j]
7523
- leverage = self.safe_string(obj, 'lever_rate')
7524
- ladders = self.safe_value(obj, 'ladders', [])
7525
- for k in range(0, len(ladders)):
7526
- bracket = ladders[k]
7527
- adjustFactor = self.safe_string(bracket, 'adjust_factor')
7528
- tiers.append({
7529
- 'tier': self.safe_integer(bracket, 'ladder'),
7530
- 'currency': self.safe_currency_code(currency),
7531
- 'minNotional': self.safe_number(bracket, 'min_size'),
7532
- 'maxNotional': self.safe_number(bracket, 'max_size'),
7533
- 'maintenanceMarginRate': self.parse_number(Precise.string_div(adjustFactor, leverage)),
7534
- 'maxLeverage': self.parse_number(leverage),
7535
- 'info': bracket,
7536
- })
7537
- result[symbol] = tiers
7538
- return result
7878
+ def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
7879
+ currencyId = self.safe_string(info, 'trade_partition')
7880
+ marketId = self.safe_string(info, 'contract_code')
7881
+ tiers = []
7882
+ brackets = self.safe_list(info, 'list', [])
7883
+ for i in range(0, len(brackets)):
7884
+ item = brackets[i]
7885
+ leverage = self.safe_string(item, 'lever_rate')
7886
+ ladders = self.safe_list(item, 'ladders', [])
7887
+ for k in range(0, len(ladders)):
7888
+ bracket = ladders[k]
7889
+ adjustFactor = self.safe_string(bracket, 'adjust_factor')
7890
+ tiers.append({
7891
+ 'tier': self.safe_integer(bracket, 'ladder'),
7892
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
7893
+ 'currency': self.safe_currency_code(currencyId),
7894
+ 'minNotional': self.safe_number(bracket, 'min_size'),
7895
+ 'maxNotional': self.safe_number(bracket, 'max_size'),
7896
+ 'maintenanceMarginRate': self.parse_number(Precise.string_div(adjustFactor, leverage)),
7897
+ 'maxLeverage': self.parse_number(leverage),
7898
+ 'info': bracket,
7899
+ })
7900
+ return tiers
7539
7901
 
7540
7902
  async def fetch_open_interest_history(self, symbol: str, timeframe='1h', since: Int = None, limit: Int = None, params={}):
7541
7903
  """
7542
7904
  Retrieves the open interest history of a currency
7543
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-information-on-open-interest
7544
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-information-on-open-interest
7545
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-information-on-open-interest
7905
+
7906
+ https://huobiapi.github.io/docs/dm/v1/en/#query-information-on-open-interest
7907
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-information-on-open-interest
7908
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-information-on-open-interest
7909
+
7546
7910
  :param str symbol: Unified CCXT market symbol
7547
7911
  :param str timeframe: '1h', '4h', '12h', or '1d'
7548
7912
  :param int [since]: Not used by huobi api, but response parsed by CCXT
@@ -7555,7 +7919,7 @@ class htx(Exchange, ImplicitAPI):
7555
7919
  if timeframe != '1h' and timeframe != '4h' and timeframe != '12h' and timeframe != '1d':
7556
7920
  raise BadRequest(self.id + ' fetchOpenInterestHistory cannot only use the 1h, 4h, 12h and 1d timeframe')
7557
7921
  await self.load_markets()
7558
- timeframes = {
7922
+ timeframes: dict = {
7559
7923
  '1h': '60min',
7560
7924
  '4h': '4hour',
7561
7925
  '12h': '12hour',
@@ -7563,7 +7927,7 @@ class htx(Exchange, ImplicitAPI):
7563
7927
  }
7564
7928
  market = self.market(symbol)
7565
7929
  amountType = self.safe_integer_2(params, 'amount_type', 'amountType', 2)
7566
- request = {
7930
+ request: dict = {
7567
7931
  'period': timeframes[timeframe],
7568
7932
  'amount_type': amountType,
7569
7933
  }
@@ -7646,15 +8010,110 @@ class htx(Exchange, ImplicitAPI):
7646
8010
  # }
7647
8011
  #
7648
8012
  data = self.safe_value(response, 'data')
7649
- tick = self.safe_value(data, 'tick')
7650
- return self.parse_open_interests(tick, market, since, limit)
8013
+ tick = self.safe_list(data, 'tick')
8014
+ return self.parse_open_interests_history(tick, market, since, limit)
8015
+
8016
+ async def fetch_open_interests(self, symbols: Strings = None, params={}):
8017
+ """
8018
+ Retrieves the open interest for a list of symbols
8019
+
8020
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information
8021
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information
8022
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information
8023
+
8024
+ :param str[] [symbols]: a list of unified CCXT market symbols
8025
+ :param dict [params]: exchange specific parameters
8026
+ :returns dict[]: a list of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
8027
+ """
8028
+ await self.load_markets()
8029
+ symbols = self.market_symbols(symbols)
8030
+ market = None
8031
+ if symbols is not None:
8032
+ symbolsLength = len(symbols)
8033
+ if symbolsLength > 0:
8034
+ first = self.safe_string(symbols, 0)
8035
+ market = self.market(first)
8036
+ request: dict = {}
8037
+ subType = None
8038
+ subType, params = self.handle_sub_type_and_params('fetchPositions', market, params, 'linear')
8039
+ marketType = None
8040
+ marketType, params = self.handle_market_type_and_params('fetchPositions', market, params)
8041
+ response = None
8042
+ if marketType == 'future':
8043
+ response = await self.contractPublicGetApiV1ContractOpenInterest(self.extend(request, params))
8044
+ #
8045
+ # {
8046
+ # "status": "ok",
8047
+ # "data": [
8048
+ # {
8049
+ # "volume": 118850.000000000000000000,
8050
+ # "amount": 635.502025211544374189,
8051
+ # "symbol": "BTC",
8052
+ # "contract_type": "self_week",
8053
+ # "contract_code": "BTC220930",
8054
+ # "trade_amount": 1470.9400749347598691119206024033947897351,
8055
+ # "trade_volume": 286286,
8056
+ # "trade_turnover": 28628600.000000000000000000
8057
+ # }
8058
+ # ],
8059
+ # "ts": 1664337928805
8060
+ # }
8061
+ #
8062
+ elif subType == 'inverse':
8063
+ response = await self.contractPublicGetSwapApiV1SwapOpenInterest(self.extend(request, params))
8064
+ #
8065
+ # {
8066
+ # "status": "ok",
8067
+ # "data": [
8068
+ # {
8069
+ # "volume": 518018.000000000000000000,
8070
+ # "amount": 2769.675777407074725180,
8071
+ # "symbol": "BTC",
8072
+ # "contract_code": "BTC-USD",
8073
+ # "trade_amount": 9544.4032080046491323463688602729806842458,
8074
+ # "trade_volume": 1848448,
8075
+ # "trade_turnover": 184844800.000000000000000000
8076
+ # }
8077
+ # ],
8078
+ # "ts": 1664337226028
8079
+ # }
8080
+ #
8081
+ else:
8082
+ request['contract_type'] = 'swap'
8083
+ response = await self.contractPublicGetLinearSwapApiV1SwapOpenInterest(self.extend(request, params))
8084
+ #
8085
+ # {
8086
+ # "status": "ok",
8087
+ # "data": [
8088
+ # {
8089
+ # "volume": 7192610.000000000000000000,
8090
+ # "amount": 7192.610000000000000000,
8091
+ # "symbol": "BTC",
8092
+ # "value": 134654290.332000000000000000,
8093
+ # "contract_code": "BTC-USDT",
8094
+ # "trade_amount": 70692.804,
8095
+ # "trade_volume": 70692804,
8096
+ # "trade_turnover": 1379302592.9518,
8097
+ # "business_type": "swap",
8098
+ # "pair": "BTC-USDT",
8099
+ # "contract_type": "swap",
8100
+ # "trade_partition": "USDT"
8101
+ # }
8102
+ # ],
8103
+ # "ts": 1664336503144
8104
+ # }
8105
+ #
8106
+ data = self.safe_list(response, 'data', [])
8107
+ return self.parse_open_interests(data, symbols)
7651
8108
 
7652
8109
  async def fetch_open_interest(self, symbol: str, params={}):
7653
8110
  """
7654
8111
  Retrieves the open interest of a currency
7655
- :see: https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information
7656
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information
7657
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information
8112
+
8113
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information
8114
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information
8115
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information
8116
+
7658
8117
  :param str symbol: Unified CCXT market symbol
7659
8118
  :param dict [params]: exchange specific parameters
7660
8119
  :returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
@@ -7665,7 +8124,7 @@ class htx(Exchange, ImplicitAPI):
7665
8124
  raise BadRequest(self.id + ' fetchOpenInterest() supports contract markets only')
7666
8125
  if market['option']:
7667
8126
  raise NotSupported(self.id + ' fetchOpenInterest() does not currently support option markets')
7668
- request = {
8127
+ request: dict = {
7669
8128
  'contract_code': market['id'],
7670
8129
  }
7671
8130
  response = None
@@ -7805,8 +8264,9 @@ class htx(Exchange, ImplicitAPI):
7805
8264
  timestamp = self.safe_integer(interest, 'ts')
7806
8265
  amount = self.safe_number(interest, 'volume')
7807
8266
  value = self.safe_number(interest, 'value')
8267
+ marketId = self.safe_string(interest, 'contract_code')
7808
8268
  return self.safe_open_interest({
7809
- 'symbol': self.safe_string(market, 'symbol'),
8269
+ 'symbol': self.safe_symbol(marketId, market),
7810
8270
  'baseVolume': amount, # deprecated
7811
8271
  'quoteVolume': value, # deprecated
7812
8272
  'openInterestAmount': amount,
@@ -7819,8 +8279,10 @@ class htx(Exchange, ImplicitAPI):
7819
8279
  async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
7820
8280
  """
7821
8281
  create a loan to borrow margin
7822
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
7823
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8282
+
8283
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
8284
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8285
+
7824
8286
  :param str symbol: unified market symbol, required for isolated margin
7825
8287
  :param str code: unified currency code of the currency to borrow
7826
8288
  :param float amount: the amount to borrow
@@ -7830,7 +8292,7 @@ class htx(Exchange, ImplicitAPI):
7830
8292
  await self.load_markets()
7831
8293
  currency = self.currency(code)
7832
8294
  market = self.market(symbol)
7833
- request = {
8295
+ request: dict = {
7834
8296
  'currency': currency['id'],
7835
8297
  'amount': self.currency_to_precision(code, amount),
7836
8298
  'symbol': market['id'],
@@ -7852,8 +8314,10 @@ class htx(Exchange, ImplicitAPI):
7852
8314
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
7853
8315
  """
7854
8316
  create a loan to borrow margin
7855
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
7856
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8317
+
8318
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
8319
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8320
+
7857
8321
  :param str code: unified currency code of the currency to borrow
7858
8322
  :param float amount: the amount to borrow
7859
8323
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7861,7 +8325,7 @@ class htx(Exchange, ImplicitAPI):
7861
8325
  """
7862
8326
  await self.load_markets()
7863
8327
  currency = self.currency(code)
7864
- request = {
8328
+ request: dict = {
7865
8329
  'currency': currency['id'],
7866
8330
  'amount': self.currency_to_precision(code, amount),
7867
8331
  }
@@ -7882,17 +8346,19 @@ class htx(Exchange, ImplicitAPI):
7882
8346
  async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
7883
8347
  """
7884
8348
  repay borrowed margin and interest
7885
- :see: https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8349
+
8350
+ https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8351
+
8352
+ :param str symbol: unified market symbol
7886
8353
  :param str code: unified currency code of the currency to repay
7887
8354
  :param float amount: the amount to repay
7888
- :param str symbol: unified market symbol
7889
8355
  :param dict [params]: extra parameters specific to the exchange API endpoint
7890
8356
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
7891
8357
  """
7892
8358
  await self.load_markets()
7893
8359
  currency = self.currency(code)
7894
8360
  accountId = await self.fetch_account_id_by_type('spot', 'isolated', symbol, params)
7895
- request = {
8361
+ request: dict = {
7896
8362
  'currency': currency['id'],
7897
8363
  'amount': self.currency_to_precision(code, amount),
7898
8364
  'accountId': accountId,
@@ -7920,7 +8386,9 @@ class htx(Exchange, ImplicitAPI):
7920
8386
  async def repay_cross_margin(self, code: str, amount, params={}):
7921
8387
  """
7922
8388
  repay borrowed margin and interest
7923
- :see: https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8389
+
8390
+ https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8391
+
7924
8392
  :param str code: unified currency code of the currency to repay
7925
8393
  :param float amount: the amount to repay
7926
8394
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7929,7 +8397,7 @@ class htx(Exchange, ImplicitAPI):
7929
8397
  await self.load_markets()
7930
8398
  currency = self.currency(code)
7931
8399
  accountId = await self.fetch_account_id_by_type('spot', 'cross', None, params)
7932
- request = {
8400
+ request: dict = {
7933
8401
  'currency': currency['id'],
7934
8402
  'amount': self.currency_to_precision(code, amount),
7935
8403
  'accountId': accountId,
@@ -7989,6 +8457,11 @@ class htx(Exchange, ImplicitAPI):
7989
8457
  async def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7990
8458
  """
7991
8459
  Fetches historical settlement records
8460
+
8461
+ https://huobiapi.github.io/docs/dm/v1/en/#query-historical-settlement-records-of-the-platform-interface
8462
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-settlement-records-of-the-platform-interface
8463
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-settlement-records-of-the-platform-interface
8464
+
7992
8465
  :param str symbol: unified symbol of the market to fetch the settlement history for
7993
8466
  :param int [since]: timestamp in ms, value range = current time - 90 days,default = current time - 90 days
7994
8467
  :param int [limit]: page items, default 20, shall not exceed 50
@@ -8000,10 +8473,10 @@ class htx(Exchange, ImplicitAPI):
8000
8473
  """
8001
8474
  if symbol is None:
8002
8475
  raise ArgumentsRequired(self.id + ' fetchSettlementHistory() requires a symbol argument')
8003
- until = self.safe_integer_2(params, 'until', 'till')
8004
- params = self.omit(params, ['until', 'till'])
8476
+ until = self.safe_integer(params, 'until')
8477
+ params = self.omit(params, ['until'])
8005
8478
  market = self.market(symbol)
8006
- request = {}
8479
+ request: dict = {}
8007
8480
  if market['future']:
8008
8481
  request['symbol'] = market['baseId']
8009
8482
  else:
@@ -8082,7 +8555,9 @@ class htx(Exchange, ImplicitAPI):
8082
8555
  async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
8083
8556
  """
8084
8557
  fetch deposit and withdraw fees
8085
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-currencies-v2
8558
+
8559
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-currencies-v2
8560
+
8086
8561
  :param str[]|None codes: list of unified currency codes
8087
8562
  :param dict [params]: extra parameters specific to the exchange API endpoint
8088
8563
  :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -8125,7 +8600,7 @@ class htx(Exchange, ImplicitAPI):
8125
8600
  # ]
8126
8601
  # }
8127
8602
  #
8128
- data = self.safe_value(response, 'data')
8603
+ data = self.safe_list(response, 'data')
8129
8604
  return self.parse_deposit_withdraw_fees(data, codes, 'currency')
8130
8605
 
8131
8606
  def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
@@ -8234,7 +8709,7 @@ class htx(Exchange, ImplicitAPI):
8234
8709
  list = self.safe_value(settlement, 'list')
8235
8710
  if list is not None:
8236
8711
  timestamp = self.safe_integer(settlement, 'settlement_time')
8237
- timestampDetails = {
8712
+ timestampDetails: dict = {
8238
8713
  'timestamp': timestamp,
8239
8714
  'datetime': self.iso8601(timestamp),
8240
8715
  }
@@ -8283,9 +8758,11 @@ class htx(Exchange, ImplicitAPI):
8283
8758
  async def fetch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}):
8284
8759
  """
8285
8760
  retrieves the public liquidations of a trading pair
8286
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-liquidation-orders-new
8287
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-liquidation-orders-new
8288
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-liquidation-order-information-new
8761
+
8762
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-liquidation-orders-new
8763
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-liquidation-orders-new
8764
+ https://huobiapi.github.io/docs/dm/v1/en/#query-liquidation-order-information-new
8765
+
8289
8766
  :param str symbol: unified CCXT market symbol
8290
8767
  :param int [since]: the earliest time in ms to fetch liquidations for
8291
8768
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -8297,7 +8774,7 @@ class htx(Exchange, ImplicitAPI):
8297
8774
  await self.load_markets()
8298
8775
  market = self.market(symbol)
8299
8776
  tradeType = self.safe_integer(params, 'trade_type', 0)
8300
- request = {
8777
+ request: dict = {
8301
8778
  'trade_type': tradeType,
8302
8779
  }
8303
8780
  if since is not None:
@@ -8338,7 +8815,7 @@ class htx(Exchange, ImplicitAPI):
8338
8815
  # "ts": 1604312615051
8339
8816
  # }
8340
8817
  #
8341
- data = self.safe_value(response, 'data', [])
8818
+ data = self.safe_list(response, 'data', [])
8342
8819
  return self.parse_liquidations(data, market, since, limit)
8343
8820
 
8344
8821
  def parse_liquidation(self, liquidation, market: Market = None):
@@ -8372,11 +8849,66 @@ class htx(Exchange, ImplicitAPI):
8372
8849
  'datetime': self.iso8601(timestamp),
8373
8850
  })
8374
8851
 
8852
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
8853
+ """
8854
+ closes open positions for a contract market, requires 'amount' in params, unlike other exchanges
8855
+
8856
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-lightning-close-order # USDT-M(isolated)
8857
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-lightning-close-position # USDT-M(cross)
8858
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-lightning-close-order # Coin-M swap
8859
+ https://huobiapi.github.io/docs/dm/v1/en/#place-flash-close-order # Coin-M futures
8860
+
8861
+ :param str symbol: unified CCXT market symbol
8862
+ :param str side: 'buy' or 'sell', the side of the closing order, opposite side side
8863
+ :param dict [params]: extra parameters specific to the okx api endpoint
8864
+ :param str [params.clientOrderId]: client needs to provide unique API and have to maintain the API themselves afterwards. [1, 9223372036854775807]
8865
+ :param dict [params.marginMode]: 'cross' or 'isolated', required for linear markets
8866
+
8867
+ EXCHANGE SPECIFIC PARAMETERS
8868
+ :param number [params.amount]: order quantity
8869
+ :param str [params.order_price_type]: 'lightning' by default, 'lightning_fok': lightning fok type, 'lightning_ioc': lightning ioc type 'market' by default, 'market': market order type, 'lightning_fok': lightning
8870
+ :returns dict: `an order structure <https://docs.ccxt.com/#/?id=position-structure>`
8871
+ """
8872
+ await self.load_markets()
8873
+ market = self.market(symbol)
8874
+ clientOrderId = self.safe_string(params, 'clientOrderId')
8875
+ if not market['contract']:
8876
+ raise BadRequest(self.id + ' closePosition() symbol supports contract markets only')
8877
+ self.check_required_argument('closePosition', side, 'side')
8878
+ request: dict = {
8879
+ 'contract_code': market['id'],
8880
+ 'direction': side,
8881
+ }
8882
+ if clientOrderId is not None:
8883
+ request['client_order_id'] = clientOrderId
8884
+ if market['inverse']:
8885
+ amount = self.safe_string_2(params, 'volume', 'amount')
8886
+ if amount is None:
8887
+ raise ArgumentsRequired(self.id + ' closePosition() requires an extra argument params["amount"] for inverse markets')
8888
+ request['volume'] = self.amount_to_precision(symbol, amount)
8889
+ params = self.omit(params, ['clientOrderId', 'volume', 'amount'])
8890
+ response = None
8891
+ if market['inverse']: # Coin-M
8892
+ if market['swap']:
8893
+ response = await self.contractPrivatePostSwapApiV1SwapLightningClosePosition(self.extend(request, params))
8894
+ else: # future
8895
+ response = await self.contractPrivatePostApiV1LightningClosePosition(self.extend(request, params))
8896
+ else: # USDT-M
8897
+ marginMode = None
8898
+ marginMode, params = self.handle_margin_mode_and_params('closePosition', params, 'cross')
8899
+ if marginMode == 'cross':
8900
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossLightningClosePosition(self.extend(request, params))
8901
+ else: # isolated
8902
+ response = await self.contractPrivatePostLinearSwapApiV1SwapLightningClosePosition(self.extend(request, params))
8903
+ return self.parse_order(response, market)
8904
+
8375
8905
  async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
8376
8906
  """
8377
8907
  set hedged to True or False
8378
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-position-mode
8379
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-position-mode
8908
+
8909
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-position-mode
8910
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-position-mode
8911
+
8380
8912
  :param bool hedged: set to True to for hedged mode, must be set separately for each market in isolated margin mode, only valid for linear markets
8381
8913
  :param str [symbol]: unified market symbol, required for isolated margin mode
8382
8914
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -8390,7 +8922,7 @@ class htx(Exchange, ImplicitAPI):
8390
8922
  market = self.market(symbol)
8391
8923
  marginMode = None
8392
8924
  marginMode, params = self.handle_margin_mode_and_params('setPositionMode', params, 'cross')
8393
- request = {
8925
+ request: dict = {
8394
8926
  'position_mode': posMode,
8395
8927
  }
8396
8928
  response = None