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/htx.py CHANGED
@@ -6,9 +6,10 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.htx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
12
13
  from ccxt.base.errors import PermissionDenied
13
14
  from ccxt.base.errors import AccountNotEnabled
14
15
  from ccxt.base.errors import ArgumentsRequired
@@ -18,12 +19,11 @@ from ccxt.base.errors import InsufficientFunds
18
19
  from ccxt.base.errors import InvalidOrder
19
20
  from ccxt.base.errors import OrderNotFound
20
21
  from ccxt.base.errors import NotSupported
21
- from ccxt.base.errors import NetworkError
22
+ from ccxt.base.errors import OperationFailed
22
23
  from ccxt.base.errors import RateLimitExceeded
23
24
  from ccxt.base.errors import ExchangeNotAvailable
24
25
  from ccxt.base.errors import OnMaintenance
25
26
  from ccxt.base.errors import RequestTimeout
26
- from ccxt.base.errors import AuthenticationError
27
27
  from ccxt.base.decimal_to_precision import TRUNCATE
28
28
  from ccxt.base.decimal_to_precision import TICK_SIZE
29
29
  from ccxt.base.precise import Precise
@@ -53,8 +53,11 @@ class htx(Exchange, ImplicitAPI):
53
53
  'borrowCrossMargin': True,
54
54
  'borrowIsolatedMargin': True,
55
55
  'cancelAllOrders': True,
56
+ 'cancelAllOrdersAfter': True,
56
57
  'cancelOrder': True,
57
58
  'cancelOrders': True,
59
+ 'closeAllPositions': False,
60
+ 'closePosition': True,
58
61
  'createDepositAddress': None,
59
62
  'createMarketBuyOrderWithCost': True,
60
63
  'createMarketOrderWithCost': False,
@@ -102,7 +105,8 @@ class htx(Exchange, ImplicitAPI):
102
105
  'fetchLeverage': False,
103
106
  'fetchLeverageTiers': True,
104
107
  'fetchLiquidations': True,
105
- 'fetchMarketLeverageTiers': True,
108
+ 'fetchMarginAdjustmentHistory': False,
109
+ 'fetchMarketLeverageTiers': 'emulated',
106
110
  'fetchMarkets': True,
107
111
  'fetchMarkOHLCV': True,
108
112
  'fetchMyLiquidations': False,
@@ -110,6 +114,7 @@ class htx(Exchange, ImplicitAPI):
110
114
  'fetchOHLCV': True,
111
115
  'fetchOpenInterest': True,
112
116
  'fetchOpenInterestHistory': True,
117
+ 'fetchOpenInterests': True,
113
118
  'fetchOpenOrder': None,
114
119
  'fetchOpenOrders': True,
115
120
  'fetchOrder': True,
@@ -118,7 +123,9 @@ class htx(Exchange, ImplicitAPI):
118
123
  'fetchOrders': True,
119
124
  'fetchOrderTrades': True,
120
125
  'fetchPosition': True,
126
+ 'fetchPositionHistory': 'emulated',
121
127
  'fetchPositions': True,
128
+ 'fetchPositionsHistory': False,
122
129
  'fetchPositionsRisk': False,
123
130
  'fetchPremiumIndexOHLCV': True,
124
131
  'fetchSettlementHistory': True,
@@ -196,7 +203,7 @@ class htx(Exchange, ImplicitAPI):
196
203
  },
197
204
  'www': 'https://www.huobi.com',
198
205
  'referral': {
199
- 'url': 'https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=6rmm2223',
206
+ 'url': 'https://www.htx.com.vc/invite/en-us/1h?invite_code=6rmm2223',
200
207
  'discount': 0.15,
201
208
  },
202
209
  'doc': [
@@ -957,16 +964,12 @@ class htx(Exchange, ImplicitAPI):
957
964
  'fetchMarkets': {
958
965
  'types': {
959
966
  'spot': True,
960
- 'future': {
961
- 'linear': True,
962
- 'inverse': True,
963
- },
964
- 'swap': {
965
- 'linear': True,
966
- 'inverse': True,
967
- },
967
+ 'linear': True,
968
+ 'inverse': True,
968
969
  },
969
970
  },
971
+ 'timeDifference': 0, # the difference between system clock and exchange clock
972
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
970
973
  'fetchOHLCV': {
971
974
  'useHistoricalEndpointForSpot': True,
972
975
  },
@@ -1236,21 +1239,159 @@ class htx(Exchange, ImplicitAPI):
1236
1239
  # https://github.com/ccxt/ccxt/issues/6081
1237
1240
  # https://github.com/ccxt/ccxt/issues/3365
1238
1241
  # https://github.com/ccxt/ccxt/issues/2873
1239
- 'GET': 'Themis', # conflict with GET(Guaranteed Entrance Token, GET Protocol)
1240
- 'GTC': 'Game.com', # conflict with Gitcoin and Gastrocoin
1241
- 'HIT': 'HitChain',
1242
+ 'NGL': 'GFNGL',
1243
+ 'GET': 'THEMIS', # conflict with GET(Guaranteed Entrance Token, GET Protocol)
1244
+ 'GTC': 'GAMECOM', # conflict with Gitcoin and Gastrocoin
1245
+ 'HIT': 'HITCHAIN',
1242
1246
  # https://github.com/ccxt/ccxt/issues/7399
1243
1247
  # https://coinmarketcap.com/currencies/pnetwork/
1244
1248
  # https://coinmarketcap.com/currencies/penta/markets/
1245
1249
  # https://en.cryptonomist.ch/blog/eidoo/the-edo-to-pnt-upgrade-what-you-need-to-know-updated/
1246
- 'PNT': 'Penta',
1247
- 'SBTC': 'Super Bitcoin',
1248
- 'SOUL': 'Soulsaver',
1249
- 'BIFI': 'Bitcoin File', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
1250
+ 'PNT': 'PENTA',
1251
+ 'SBTC': 'SUPERBITCOIN',
1252
+ 'SOUL': 'SOULSAVER',
1253
+ 'BIFI': 'BITCOINFILE', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
1254
+ 'FUD': 'FTX Users Debt',
1255
+ },
1256
+ 'features': {
1257
+ 'spot': {
1258
+ 'sandbox': True,
1259
+ 'createOrder': {
1260
+ 'marginMode': True,
1261
+ 'triggerPrice': True,
1262
+ 'triggerDirection': True,
1263
+ 'triggerPriceType': None,
1264
+ 'stopLossPrice': False, # todo: add support by triggerprice
1265
+ 'takeProfitPrice': False,
1266
+ 'attachedStopLossTakeProfit': None,
1267
+ 'timeInForce': {
1268
+ 'IOC': True,
1269
+ 'FOK': True,
1270
+ 'PO': True,
1271
+ 'GTD': False,
1272
+ },
1273
+ 'hedged': False,
1274
+ 'trailing': False,
1275
+ 'iceberg': False,
1276
+ 'selfTradePrevention': True, # todo implement
1277
+ 'leverage': True, # todo implement
1278
+ 'marketBuyByCost': True,
1279
+ 'marketBuyRequiresPrice': True,
1280
+ },
1281
+ 'createOrders': {
1282
+ 'max': 10,
1283
+ },
1284
+ 'fetchMyTrades': {
1285
+ 'marginMode': False,
1286
+ 'limit': 500,
1287
+ 'daysBack': 120,
1288
+ 'untilDays': 2,
1289
+ },
1290
+ 'fetchOrder': {
1291
+ 'marginMode': False,
1292
+ 'trigger': False,
1293
+ 'trailing': False,
1294
+ },
1295
+ 'fetchOpenOrders': {
1296
+ 'marginMode': False,
1297
+ 'trigger': True,
1298
+ 'trailing': False,
1299
+ 'limit': 500,
1300
+ },
1301
+ 'fetchOrders': {
1302
+ 'marginMode': False,
1303
+ 'trigger': True,
1304
+ 'trailing': False,
1305
+ 'limit': 500,
1306
+ 'untilDays': 2,
1307
+ 'daysBack': 180,
1308
+ },
1309
+ 'fetchClosedOrders': {
1310
+ 'marginMode': False,
1311
+ 'trigger': True,
1312
+ 'trailing': False,
1313
+ 'untilDays': 2,
1314
+ 'limit': 500,
1315
+ 'daysBack': 180,
1316
+ 'daysBackCanceled': 1 / 12,
1317
+ },
1318
+ 'fetchOHLCV': {
1319
+ 'limit': 1000, # 2000 for non-historical
1320
+ },
1321
+ },
1322
+ 'forDerivatives': {
1323
+ 'extends': 'spot',
1324
+ 'createOrder': {
1325
+ 'stopLossPrice': True,
1326
+ 'takeProfitPrice': True,
1327
+ 'trailing': True,
1328
+ 'hedged': True,
1329
+ # 'leverage': True, # todo
1330
+ },
1331
+ 'createOrders': {
1332
+ 'max': 25,
1333
+ },
1334
+ 'fetchOrder': {
1335
+ 'marginMode': True,
1336
+ },
1337
+ 'fetchOpenOrders': {
1338
+ 'marginMode': True,
1339
+ 'trigger': False,
1340
+ 'trailing': False,
1341
+ 'limit': 50,
1342
+ },
1343
+ 'fetchOrders': {
1344
+ 'marginMode': True,
1345
+ 'trigger': False,
1346
+ 'trailing': False,
1347
+ 'limit': 50,
1348
+ 'daysBack': 90,
1349
+ },
1350
+ 'fetchClosedOrders': {
1351
+ 'marginMode': True,
1352
+ 'trigger': False,
1353
+ 'trailing': False,
1354
+ 'untilDays': 2,
1355
+ 'limit': 50,
1356
+ 'daysBack': 90,
1357
+ 'daysBackCanceled': 1 / 12,
1358
+ },
1359
+ 'fetchOHLCV': {
1360
+ 'limit': 2000,
1361
+ },
1362
+ },
1363
+ 'swap': {
1364
+ 'linear': {
1365
+ 'extends': 'forDerivatives',
1366
+ },
1367
+ 'inverse': {
1368
+ 'extends': 'forDerivatives',
1369
+ },
1370
+ },
1371
+ 'future': {
1372
+ 'linear': {
1373
+ 'extends': 'forDerivatives',
1374
+ },
1375
+ 'inverse': {
1376
+ 'extends': 'forDerivatives',
1377
+ },
1378
+ },
1250
1379
  },
1251
1380
  })
1252
1381
 
1253
1382
  def fetch_status(self, params={}):
1383
+ """
1384
+ the latest known information on the availability of the exchange API
1385
+
1386
+ https://huobiapi.github.io/docs/spot/v1/en/#get-system-status
1387
+ https://huobiapi.github.io/docs/dm/v1/en/#get-system-status
1388
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-system-status
1389
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#get-system-status
1390
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#query-whether-the-system-is-available # contractPublicGetHeartbeat
1391
+
1392
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1393
+ :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
1394
+ """
1254
1395
  self.load_markets()
1255
1396
  marketType = None
1256
1397
  marketType, params = self.handle_market_type_and_params('fetchStatus', None, params)
@@ -1462,6 +1603,10 @@ class htx(Exchange, ImplicitAPI):
1462
1603
  def fetch_time(self, params={}):
1463
1604
  """
1464
1605
  fetches the current integer timestamp in milliseconds from the exchange server
1606
+
1607
+ https://huobiapi.github.io/docs/spot/v1/en/#get-current-timestamp
1608
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-current-system-timestamp
1609
+
1465
1610
  :param dict [params]: extra parameters specific to the exchange API endpoint
1466
1611
  :returns int: the current integer timestamp in milliseconds from the exchange server
1467
1612
  """
@@ -1485,7 +1630,7 @@ class htx(Exchange, ImplicitAPI):
1485
1630
  #
1486
1631
  return self.safe_integer_2(response, 'data', 'ts')
1487
1632
 
1488
- def parse_trading_fee(self, fee, market: Market = None):
1633
+ def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
1489
1634
  #
1490
1635
  # {
1491
1636
  # "symbol":"btcusdt",
@@ -1501,18 +1646,23 @@ class htx(Exchange, ImplicitAPI):
1501
1646
  'symbol': self.safe_symbol(marketId, market),
1502
1647
  'maker': self.safe_number(fee, 'actualMakerRate'),
1503
1648
  'taker': self.safe_number(fee, 'actualTakerRate'),
1649
+ 'percentage': None,
1650
+ 'tierBased': None,
1504
1651
  }
1505
1652
 
1506
- def fetch_trading_fee(self, symbol: str, params={}):
1653
+ def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
1507
1654
  """
1508
1655
  fetch the trading fees for a market
1656
+
1657
+ https://huobiapi.github.io/docs/spot/v1/en/#get-current-fee-rate-applied-to-the-user
1658
+
1509
1659
  :param str symbol: unified market symbol
1510
1660
  :param dict [params]: extra parameters specific to the exchange API endpoint
1511
1661
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
1512
1662
  """
1513
1663
  self.load_markets()
1514
1664
  market = self.market(symbol)
1515
- request = {
1665
+ request: dict = {
1516
1666
  'symbols': market['id'], # trading symbols comma-separated
1517
1667
  }
1518
1668
  response = self.spotPrivateGetV2ReferenceTransactFeeRate(self.extend(request, params))
@@ -1542,14 +1692,23 @@ class htx(Exchange, ImplicitAPI):
1542
1692
  self.load_markets()
1543
1693
  if symbols is None:
1544
1694
  symbols = self.symbols
1545
- result = {}
1695
+ result: dict = {}
1546
1696
  for i in range(0, len(symbols)):
1547
1697
  symbol = symbols[i]
1548
1698
  result[symbol] = self.fetch_trading_limits_by_id(self.market_id(symbol), params)
1549
1699
  return result
1550
1700
 
1551
1701
  def fetch_trading_limits_by_id(self, id: str, params={}):
1552
- request = {
1702
+ """
1703
+ @ignore
1704
+
1705
+ https://huobiapi.github.io/docs/spot/v1/en/#get-current-fee-rate-applied-to-the-user
1706
+
1707
+ :param str id: market id
1708
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1709
+ :returns dict: the limits object of a market structure
1710
+ """
1711
+ request: dict = {
1553
1712
  'symbol': id,
1554
1713
  }
1555
1714
  response = self.spotPublicGetV1CommonExchange(self.extend(request, params))
@@ -1600,58 +1759,69 @@ class htx(Exchange, ImplicitAPI):
1600
1759
  def cost_to_precision(self, symbol, cost):
1601
1760
  return self.decimal_to_precision(cost, TRUNCATE, self.markets[symbol]['precision']['cost'], self.precisionMode)
1602
1761
 
1603
- def fetch_markets(self, params={}):
1762
+ def fetch_markets(self, params={}) -> List[Market]:
1604
1763
  """
1605
1764
  retrieves data on all markets for huobi
1765
+
1766
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
1767
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
1768
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
1769
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
1770
+
1606
1771
  :param dict [params]: extra parameters specific to the exchange API endpoint
1607
1772
  :returns dict[]: an array of objects representing market data
1608
1773
  """
1609
- options = self.safe_value(self.options, 'fetchMarkets', {})
1610
- types = self.safe_value(options, 'types', {})
1774
+ if self.options['adjustForTimeDifference']:
1775
+ self.load_time_difference()
1776
+ types = None
1777
+ types, params = self.handle_option_and_params(params, 'fetchMarkets', 'types', {})
1611
1778
  allMarkets = []
1612
1779
  promises = []
1613
1780
  keys = list(types.keys())
1614
1781
  for i in range(0, len(keys)):
1615
- type = keys[i]
1616
- value = self.safe_value(types, type)
1617
- if value is True:
1618
- promises.append(self.fetch_markets_by_type_and_sub_type(type, None, params))
1619
- elif value:
1620
- subKeys = list(value.keys())
1621
- for j in range(0, len(subKeys)):
1622
- subType = subKeys[j]
1623
- subValue = self.safe_value(value, subType)
1624
- if subValue:
1625
- promises.append(self.fetch_markets_by_type_and_sub_type(type, subType, params))
1782
+ key = keys[i]
1783
+ if self.safe_bool(types, key):
1784
+ if key == 'spot':
1785
+ promises.append(self.fetch_markets_by_type_and_sub_type('spot', None, params))
1786
+ elif key == 'linear':
1787
+ promises.append(self.fetch_markets_by_type_and_sub_type(None, 'linear', params))
1788
+ elif key == 'inverse':
1789
+ promises.append(self.fetch_markets_by_type_and_sub_type('swap', 'inverse', params))
1790
+ promises.append(self.fetch_markets_by_type_and_sub_type('future', 'inverse', params))
1626
1791
  promises = promises
1627
1792
  for i in range(0, len(promises)):
1628
1793
  allMarkets = self.array_concat(allMarkets, promises[i])
1629
1794
  return allMarkets
1630
1795
 
1631
- def fetch_markets_by_type_and_sub_type(self, type, subType, params={}):
1632
- query = self.omit(params, ['type', 'subType'])
1633
- spot = (type == 'spot')
1634
- contract = (type != 'spot')
1635
- future = (type == 'future')
1636
- swap = (type == 'swap')
1637
- linear = None
1638
- inverse = None
1639
- request = {}
1796
+ def fetch_markets_by_type_and_sub_type(self, type: Str, subType: Str, params={}):
1797
+ """
1798
+ @ignore
1799
+ retrieves data on all markets of a certain type and/or subtype
1800
+
1801
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
1802
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
1803
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
1804
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
1805
+
1806
+ :param str [type]: 'spot', 'swap' or 'future'
1807
+ :param str [subType]: 'linear' or 'inverse'
1808
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1809
+ :returns dict[]: an array of objects representing market data
1810
+ """
1811
+ isSpot = (type == 'spot')
1812
+ request: dict = {}
1640
1813
  response = None
1641
- if contract:
1642
- linear = (subType == 'linear')
1643
- inverse = (subType == 'inverse')
1644
- if linear:
1645
- if future:
1646
- request['business_type'] = 'futures'
1647
- response = self.contractPublicGetLinearSwapApiV1SwapContractInfo(self.extend(request, query))
1648
- elif inverse:
1649
- if future:
1650
- response = self.contractPublicGetApiV1ContractContractInfo(self.extend(request, query))
1651
- elif swap:
1652
- response = self.contractPublicGetSwapApiV1SwapContractInfo(self.extend(request, query))
1814
+ if not isSpot:
1815
+ if subType == 'linear':
1816
+ request['business_type'] = 'all' # override default to fetch all linear markets
1817
+ response = self.contractPublicGetLinearSwapApiV1SwapContractInfo(self.extend(request, params))
1818
+ elif subType == 'inverse':
1819
+ if type == 'future':
1820
+ response = self.contractPublicGetApiV1ContractContractInfo(self.extend(request, params))
1821
+ elif type == 'swap':
1822
+ response = self.contractPublicGetSwapApiV1SwapContractInfo(self.extend(request, params))
1653
1823
  else:
1654
- response = self.spotPublicGetV1CommonSymbols(self.extend(request, query))
1824
+ response = self.spotPublicGetV1CommonSymbols(self.extend(request, params))
1655
1825
  #
1656
1826
  # spot
1657
1827
  #
@@ -1690,75 +1860,58 @@ class htx(Exchange, ImplicitAPI):
1690
1860
  # ]
1691
1861
  # }
1692
1862
  #
1693
- # inverse future
1863
+ # inverse(swap & future)
1694
1864
  #
1695
1865
  # {
1696
1866
  # "status":"ok",
1697
1867
  # "data":[
1698
1868
  # {
1699
1869
  # "symbol":"BTC",
1700
- # "contract_code":"BTC211126",
1701
- # "contract_type":"self_week",
1702
- # "contract_size":100.000000000000000000,
1703
- # "price_tick":0.010000000000000000,
1704
- # "delivery_date":"20211126",
1705
- # "delivery_time":"1637913600000",
1870
+ # "contract_code":"BTC211126", #/ BTC-USD in swap
1871
+ # "contract_type":"self_week", # only in future
1872
+ # "contract_size":100,
1873
+ # "price_tick":0.1,
1874
+ # "delivery_date":"20211126", # only in future
1875
+ # "delivery_time":"1637913600000", # empty in swap
1706
1876
  # "create_date":"20211112",
1707
1877
  # "contract_status":1,
1708
- # "settlement_time":"1637481600000"
1878
+ # "settlement_time":"1637481600000" # only in future
1879
+ # "settlement_date":"16xxxxxxxxxxx" # only in swap
1709
1880
  # },
1881
+ # ...
1710
1882
  # ],
1711
1883
  # "ts":1637474595140
1712
1884
  # }
1713
1885
  #
1714
- # linear futures
1886
+ # linear(swap & future)
1715
1887
  #
1716
1888
  # {
1717
1889
  # "status":"ok",
1718
1890
  # "data":[
1719
1891
  # {
1720
1892
  # "symbol":"BTC",
1721
- # "contract_code":"BTC-USDT-211231",
1722
- # "contract_size":0.001000000000000000,
1723
- # "price_tick":0.100000000000000000,
1724
- # "delivery_date":"20211231",
1725
- # "delivery_time":"1640937600000",
1893
+ # "contract_code":"BTC-USDT-211231", # or "BTC-USDT" in swap
1894
+ # "contract_size":0.001,
1895
+ # "price_tick":0.1,
1896
+ # "delivery_date":"20211231", # empty in swap
1897
+ # "delivery_time":"1640937600000", # empty in swap
1726
1898
  # "create_date":"20211228",
1727
1899
  # "contract_status":1,
1728
1900
  # "settlement_date":"1640764800000",
1729
- # "support_margin_mode":"cross",
1730
- # "business_type":"futures",
1901
+ # "support_margin_mode":"cross", # "all" or "cross"
1902
+ # "business_type":"futures", # "swap" or "futures"
1731
1903
  # "pair":"BTC-USDT",
1732
- # "contract_type":"self_week" # next_week, quarter
1733
- # },
1904
+ # "contract_type":"self_week", # "swap", "self_week", "next_week", "quarter"
1905
+ # "trade_partition":"USDT",
1906
+ # }
1734
1907
  # ],
1735
1908
  # "ts":1640736207263
1736
1909
  # }
1737
1910
  #
1738
- # swaps
1739
- #
1740
- # {
1741
- # "status":"ok",
1742
- # "data":[
1743
- # {
1744
- # "symbol":"BTC",
1745
- # "contract_code":"BTC-USDT",
1746
- # "contract_size":0.001000000000000000,
1747
- # "price_tick":0.100000000000000000,
1748
- # "delivery_time":"",
1749
- # "create_date":"20201021",
1750
- # "contract_status":1,
1751
- # "settlement_date":"1637481600000",
1752
- # "support_margin_mode":"all", # isolated
1753
- # },
1754
- # ],
1755
- # "ts":1637474774467
1756
- # }
1757
- #
1758
- markets = self.safe_value(response, 'data', [])
1911
+ markets = self.safe_list(response, 'data', [])
1759
1912
  numMarkets = len(markets)
1760
1913
  if numMarkets < 1:
1761
- raise NetworkError(self.id + ' fetchMarkets() returned an empty response: ' + self.json(markets))
1914
+ raise OperationFailed(self.id + ' fetchMarkets() returned an empty response: ' + self.json(response))
1762
1915
  result = []
1763
1916
  for i in range(0, len(markets)):
1764
1917
  market = markets[i]
@@ -1767,15 +1920,30 @@ class htx(Exchange, ImplicitAPI):
1767
1920
  settleId = None
1768
1921
  id = None
1769
1922
  lowercaseId = None
1923
+ contract = ('contract_code' in market)
1924
+ spot = not contract
1925
+ swap = False
1926
+ future = False
1927
+ linear = None
1928
+ inverse = None
1929
+ # check if parsed market is contract
1770
1930
  if contract:
1771
1931
  id = self.safe_string(market, 'contract_code')
1772
1932
  lowercaseId = id.lower()
1933
+ delivery_date = self.safe_string(market, 'delivery_date')
1934
+ business_type = self.safe_string(market, 'business_type')
1935
+ future = delivery_date is not None
1936
+ swap = not future
1937
+ linear = business_type is not None
1938
+ inverse = not linear
1773
1939
  if swap:
1940
+ type = 'swap'
1774
1941
  parts = id.split('-')
1775
1942
  baseId = self.safe_string_lower(market, 'symbol')
1776
1943
  quoteId = self.safe_string_lower(parts, 1)
1777
1944
  settleId = baseId if inverse else quoteId
1778
1945
  elif future:
1946
+ type = 'future'
1779
1947
  baseId = self.safe_string_lower(market, 'symbol')
1780
1948
  if inverse:
1781
1949
  quoteId = 'USD'
@@ -1786,6 +1954,7 @@ class htx(Exchange, ImplicitAPI):
1786
1954
  quoteId = self.safe_string_lower(parts, 1)
1787
1955
  settleId = quoteId
1788
1956
  else:
1957
+ type = 'spot'
1789
1958
  baseId = self.safe_string(market, 'base-currency')
1790
1959
  quoteId = self.safe_string(market, 'quote-currency')
1791
1960
  id = baseId + quoteId
@@ -1908,7 +2077,41 @@ class htx(Exchange, ImplicitAPI):
1908
2077
  })
1909
2078
  return result
1910
2079
 
1911
- def parse_ticker(self, ticker, market: Market = None) -> Ticker:
2080
+ def try_get_symbol_from_future_markets(self, symbolOrMarketId: str):
2081
+ if symbolOrMarketId in self.markets:
2082
+ return symbolOrMarketId
2083
+ # only on "future" market type(inverse & linear), market-id differs between "fetchMarkets" and "fetchTicker"
2084
+ # so we have to create a mapping
2085
+ # - market-id from fetchMarkts: `BTC-USDT-240419`(linear future) or `BTC240412`(inverse future)
2086
+ # - market-id from fetchTciker[s]: `BTC-USDT-CW` (linear future) or `BTC_CW` (inverse future)
2087
+ if not ('futureMarketIdsForSymbols' in self.options):
2088
+ self.options['futureMarketIdsForSymbols'] = {}
2089
+ futureMarketIdsForSymbols = self.safe_dict(self.options, 'futureMarketIdsForSymbols', {})
2090
+ if symbolOrMarketId in futureMarketIdsForSymbols:
2091
+ return futureMarketIdsForSymbols[symbolOrMarketId]
2092
+ futureMarkets = self.filter_by(self.markets, 'future', True)
2093
+ futuresCharsMaps: dict = {
2094
+ 'this_week': 'CW',
2095
+ 'next_week': 'NW',
2096
+ 'quarter': 'CQ',
2097
+ 'next_quarter': 'NQ',
2098
+ }
2099
+ for i in range(0, len(futureMarkets)):
2100
+ market = futureMarkets[i]
2101
+ info = self.safe_value(market, 'info', {})
2102
+ contractType = self.safe_string(info, 'contract_type')
2103
+ contractSuffix = futuresCharsMaps[contractType]
2104
+ # see comment on formats a bit above
2105
+ constructedId = market['base'] + '-' + market['quote'] + '-' + contractSuffix if market['linear'] else market['base'] + '_' + contractSuffix
2106
+ if constructedId == symbolOrMarketId:
2107
+ symbol = market['symbol']
2108
+ self.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbol
2109
+ return symbol
2110
+ # if not found, just save it to avoid unnecessary future iterations
2111
+ self.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbolOrMarketId
2112
+ return symbolOrMarketId
2113
+
2114
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1912
2115
  #
1913
2116
  # fetchTicker
1914
2117
  #
@@ -1956,6 +2159,7 @@ class htx(Exchange, ImplicitAPI):
1956
2159
  #
1957
2160
  marketId = self.safe_string_2(ticker, 'symbol', 'contract_code')
1958
2161
  symbol = self.safe_symbol(marketId, market)
2162
+ symbol = self.try_get_symbol_from_future_markets(symbol)
1959
2163
  timestamp = self.safe_integer_2(ticker, 'ts', 'quoteTime')
1960
2164
  bid = None
1961
2165
  bidVolume = None
@@ -2005,13 +2209,19 @@ class htx(Exchange, ImplicitAPI):
2005
2209
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2006
2210
  """
2007
2211
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
2212
+
2213
+ https://huobiapi.github.io/docs/spot/v1/en/#get-latest-aggregated-ticker
2214
+ https://huobiapi.github.io/docs/dm/v1/en/#get-market-data-overview
2215
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-data-overview
2216
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-data-overview
2217
+
2008
2218
  :param str symbol: unified symbol of the market to fetch the ticker for
2009
2219
  :param dict [params]: extra parameters specific to the exchange API endpoint
2010
2220
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
2011
2221
  """
2012
2222
  self.load_markets()
2013
2223
  market = self.market(symbol)
2014
- request = {}
2224
+ request: dict = {}
2015
2225
  response = None
2016
2226
  if market['linear']:
2017
2227
  request['contract_code'] = market['id']
@@ -2079,11 +2289,13 @@ class htx(Exchange, ImplicitAPI):
2079
2289
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
2080
2290
  """
2081
2291
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
2082
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-latest-tickers-for-all-pairs
2083
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
2084
- :see: https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
2085
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
2086
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2292
+
2293
+ https://huobiapi.github.io/docs/spot/v1/en/#get-latest-tickers-for-all-pairs
2294
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
2295
+ https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
2296
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
2297
+
2298
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2087
2299
  :param dict [params]: extra parameters specific to the exchange API endpoint
2088
2300
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2089
2301
  """
@@ -2093,27 +2305,37 @@ class htx(Exchange, ImplicitAPI):
2093
2305
  market = None
2094
2306
  if first is not None:
2095
2307
  market = self.market(first)
2308
+ isSubTypeRequested = ('subType' in params) or ('business_type' in params)
2096
2309
  type = None
2097
2310
  subType = None
2098
2311
  type, params = self.handle_market_type_and_params('fetchTickers', market, params)
2099
2312
  subType, params = self.handle_sub_type_and_params('fetchTickers', market, params)
2100
- request = {}
2313
+ request: dict = {}
2314
+ isSpot = (type == 'spot')
2101
2315
  future = (type == 'future')
2102
2316
  swap = (type == 'swap')
2103
2317
  linear = (subType == 'linear')
2104
2318
  inverse = (subType == 'inverse')
2105
- params = self.omit(params, ['type', 'subType'])
2106
2319
  response = None
2107
- if future or swap:
2320
+ if not isSpot or isSubTypeRequested:
2108
2321
  if linear:
2322
+ # independently of type, supports calling all linear symbols i.e. fetchTickers(None, {subType:'linear'})
2109
2323
  if future:
2110
2324
  request['business_type'] = 'futures'
2325
+ elif swap:
2326
+ request['business_type'] = 'swap'
2327
+ else:
2328
+ request['business_type'] = 'all'
2111
2329
  response = self.contractPublicGetLinearSwapExMarketDetailBatchMerged(self.extend(request, params))
2112
2330
  elif inverse:
2113
2331
  if future:
2114
2332
  response = self.contractPublicGetMarketDetailBatchMerged(self.extend(request, params))
2115
2333
  elif swap:
2116
2334
  response = self.contractPublicGetSwapExMarketDetailBatchMerged(self.extend(request, params))
2335
+ else:
2336
+ raise NotSupported(self.id + ' fetchTickers() you have to set params["type"] to either "swap" or "future" for inverse contracts')
2337
+ else:
2338
+ raise NotSupported(self.id + ' fetchTickers() you have to set params["subType"] to either "linear" or "inverse" for contracts')
2117
2339
  else:
2118
2340
  response = self.spotPublicGetMarketTickers(self.extend(request, params))
2119
2341
  #
@@ -2140,7 +2362,7 @@ class htx(Exchange, ImplicitAPI):
2140
2362
  # "ts":1639547261293
2141
2363
  # }
2142
2364
  #
2143
- # inverse swaps, linear swaps, inverse futures
2365
+ # linear swap, linear future, inverse swap, inverse future
2144
2366
  #
2145
2367
  # {
2146
2368
  # "status":"ok",
@@ -2157,74 +2379,28 @@ class htx(Exchange, ImplicitAPI):
2157
2379
  # "high":"0.10725",
2158
2380
  # "amount":"2340267.415144052378486261756692535687481566",
2159
2381
  # "count":882,
2160
- # "vol":"24706"
2382
+ # "vol":"24706",
2383
+ # "trade_turnover":"840726.5048", # only in linear futures
2384
+ # "business_type":"futures", # only in linear futures
2385
+ # "contract_code":"BTC-USDT-CW", # only in linear futures, instead of 'symbol'
2161
2386
  # }
2162
2387
  # ],
2163
2388
  # "ts":1637504679376
2164
2389
  # }
2165
2390
  #
2166
- # linear futures
2167
- #
2168
- # {
2169
- # "status":"ok",
2170
- # "ticks":[
2171
- # {
2172
- # "id":1640745627,
2173
- # "ts":1640745627957,
2174
- # "ask":[48079.1,20],
2175
- # "bid":[47713.8,125],
2176
- # "business_type":"futures",
2177
- # "contract_code":"BTC-USDT-CW",
2178
- # "open":"49011.8",
2179
- # "close":"47934",
2180
- # "low":"47292.3",
2181
- # "high":"49011.8",
2182
- # "amount":"17.398",
2183
- # "count":1515,
2184
- # "vol":"17398",
2185
- # "trade_turnover":"840726.5048"
2186
- # }
2187
- # ],
2188
- # "ts":1640745627988
2189
- # }
2190
- #
2191
- tickers = self.safe_value_2(response, 'data', 'ticks', [])
2192
- timestamp = self.safe_integer(response, 'ts')
2193
- result = {}
2194
- for i in range(0, len(tickers)):
2195
- ticker = self.parse_ticker(tickers[i])
2196
- # the market ids for linear futures are non-standard and differ from all the other endpoints
2197
- # we are doing a linear-matching here
2198
- if future and linear:
2199
- for j in range(0, len(self.symbols)):
2200
- symbolInner = self.symbols[j]
2201
- marketInner = self.market(symbolInner)
2202
- contractType = self.safe_string(marketInner['info'], 'contract_type')
2203
- if (contractType == 'this_week') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CW')):
2204
- ticker['symbol'] = marketInner['symbol']
2205
- break
2206
- elif (contractType == 'next_week') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NW')):
2207
- ticker['symbol'] = marketInner['symbol']
2208
- break
2209
- elif (contractType == 'this_quarter') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CQ')):
2210
- ticker['symbol'] = marketInner['symbol']
2211
- break
2212
- elif (contractType == 'next_quarter') and (ticker['symbol'] == (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NQ')):
2213
- ticker['symbol'] = marketInner['symbol']
2214
- break
2215
- symbol = ticker['symbol']
2216
- ticker['timestamp'] = timestamp
2217
- ticker['datetime'] = self.iso8601(timestamp)
2218
- result[symbol] = ticker
2219
- return self.filter_by_array_tickers(result, 'symbol', symbols)
2391
+ rawTickers = self.safe_list_2(response, 'data', 'ticks', [])
2392
+ tickers = self.parse_tickers(rawTickers, symbols, params)
2393
+ return self.filter_by_array_tickers(tickers, 'symbol', symbols)
2220
2394
 
2221
2395
  def fetch_last_prices(self, symbols: Strings = None, params={}):
2222
2396
  """
2223
2397
  fetches the last price for multiple markets
2224
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2225
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2226
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2227
- :param str[]|None symbols: unified symbols of the markets to fetch the last prices
2398
+
2399
+ https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2400
+ https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2401
+ https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2402
+
2403
+ :param str[] [symbols]: unified symbols of the markets to fetch the last prices
2228
2404
  :param dict [params]: extra parameters specific to the exchange API endpoint
2229
2405
  :returns dict: a dictionary of lastprices structures
2230
2406
  """
@@ -2314,7 +2490,7 @@ class htx(Exchange, ImplicitAPI):
2314
2490
  else:
2315
2491
  raise NotSupported(self.id + ' fetchLastPrices() does not support ' + type + ' markets yet')
2316
2492
  tick = self.safe_value(response, 'tick', {})
2317
- data = self.safe_value(tick, 'data', [])
2493
+ data = self.safe_list(tick, 'data', [])
2318
2494
  return self.parse_last_prices(data, symbols)
2319
2495
 
2320
2496
  def parse_last_price(self, entry, market: Market = None):
@@ -2336,6 +2512,12 @@ class htx(Exchange, ImplicitAPI):
2336
2512
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2337
2513
  """
2338
2514
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
2515
+
2516
+ https://huobiapi.github.io/docs/spot/v1/en/#get-market-depth
2517
+ https://huobiapi.github.io/docs/dm/v1/en/#get-market-depth
2518
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-depth
2519
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-depth
2520
+
2339
2521
  :param str symbol: unified symbol of the market to fetch the order book for
2340
2522
  :param int [limit]: the maximum amount of order book entries to return
2341
2523
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2343,7 +2525,7 @@ class htx(Exchange, ImplicitAPI):
2343
2525
  """
2344
2526
  self.load_markets()
2345
2527
  market = self.market(symbol)
2346
- request = {
2528
+ request: dict = {
2347
2529
  #
2348
2530
  # from the API docs
2349
2531
  #
@@ -2413,7 +2595,7 @@ class htx(Exchange, ImplicitAPI):
2413
2595
  return result
2414
2596
  raise ExchangeError(self.id + ' fetchOrderBook() returned unrecognized response: ' + self.json(response))
2415
2597
 
2416
- def parse_trade(self, trade, market: Market = None) -> Trade:
2598
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
2417
2599
  #
2418
2600
  # spot fetchTrades(public)
2419
2601
  #
@@ -2547,6 +2729,9 @@ class htx(Exchange, ImplicitAPI):
2547
2729
  def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2548
2730
  """
2549
2731
  fetch all the trades made from a single order
2732
+
2733
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2734
+
2550
2735
  :param str id: order id
2551
2736
  :param str symbol: unified market symbol
2552
2737
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2564,8 +2749,21 @@ class htx(Exchange, ImplicitAPI):
2564
2749
  return self.fetch_spot_order_trades(id, symbol, since, limit, params)
2565
2750
 
2566
2751
  def fetch_spot_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2752
+ """
2753
+ @ignore
2754
+ fetch all the trades made from a single order
2755
+
2756
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2757
+
2758
+ :param str id: order id
2759
+ :param str symbol: unified market symbol
2760
+ :param int [since]: the earliest time in ms to fetch trades for
2761
+ :param int [limit]: the maximum number of trades to retrieve
2762
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2763
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2764
+ """
2567
2765
  self.load_markets()
2568
- request = {
2766
+ request: dict = {
2569
2767
  'order-id': id,
2570
2768
  }
2571
2769
  response = self.spotPrivateGetV1OrderOrdersOrderIdMatchresults(self.extend(request, params))
@@ -2573,9 +2771,11 @@ class htx(Exchange, ImplicitAPI):
2573
2771
 
2574
2772
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2575
2773
  """
2576
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-match-results-via-multiple-fields-new
2577
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-match-results-via-multiple-fields-new
2578
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-match-results
2774
+
2775
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-match-results-via-multiple-fields-new
2776
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-match-results-via-multiple-fields-new
2777
+ https://huobiapi.github.io/docs/spot/v1/en/#search-match-results
2778
+
2579
2779
  fetch all trades made by the user
2580
2780
  :param str symbol: unified market symbol
2581
2781
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2595,7 +2795,7 @@ class htx(Exchange, ImplicitAPI):
2595
2795
  market = self.market(symbol)
2596
2796
  marketType = None
2597
2797
  marketType, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
2598
- request = {
2798
+ request: dict = {
2599
2799
  # spot -----------------------------------------------------------
2600
2800
  # 'symbol': market['id'],
2601
2801
  # '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',
@@ -2726,10 +2926,12 @@ class htx(Exchange, ImplicitAPI):
2726
2926
 
2727
2927
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = 1000, params={}) -> List[Trade]:
2728
2928
  """
2729
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-most-recent-trades
2730
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-a-batch-of-trade-records-of-a-contract
2731
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-trade-records-of-a-contract
2732
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-trade-records-of-a-contract
2929
+
2930
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-most-recent-trades
2931
+ https://huobiapi.github.io/docs/dm/v1/en/#query-a-batch-of-trade-records-of-a-contract
2932
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-trade-records-of-a-contract
2933
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-trade-records-of-a-contract
2934
+
2733
2935
  get the list of most recent trades for a particular symbol
2734
2936
  :param str symbol: unified symbol of the market to fetch trades for
2735
2937
  :param int [since]: timestamp in ms of the earliest trade to fetch
@@ -2739,7 +2941,7 @@ class htx(Exchange, ImplicitAPI):
2739
2941
  """
2740
2942
  self.load_markets()
2741
2943
  market = self.market(symbol)
2742
- request = {
2944
+ request: dict = {
2743
2945
  # 'symbol': market['id'], # spot, future
2744
2946
  # 'contract_code': market['id'], # swap
2745
2947
  }
@@ -2821,10 +3023,12 @@ class htx(Exchange, ImplicitAPI):
2821
3023
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
2822
3024
  """
2823
3025
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
2824
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles
2825
- :see: https://huobiapi.github.io/docs/dm/v1/en/#get-kline-data
2826
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-kline-data
2827
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
3026
+
3027
+ https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles
3028
+ https://huobiapi.github.io/docs/dm/v1/en/#get-kline-data
3029
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-kline-data
3030
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
3031
+
2828
3032
  :param str symbol: unified symbol of the market to fetch OHLCV data for
2829
3033
  :param str timeframe: the length of time each candle represents
2830
3034
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -2840,7 +3044,7 @@ class htx(Exchange, ImplicitAPI):
2840
3044
  if paginate:
2841
3045
  return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000)
2842
3046
  market = self.market(symbol)
2843
- request = {
3047
+ request: dict = {
2844
3048
  'period': self.safe_string(self.timeframes, timeframe, timeframe),
2845
3049
  # 'symbol': market['id'], # spot, future
2846
3050
  # 'contract_code': market['id'], # swap
@@ -2848,63 +3052,68 @@ class htx(Exchange, ImplicitAPI):
2848
3052
  # 'from': int((since / str(1000))), spot only
2849
3053
  # 'to': self.seconds(), spot only
2850
3054
  }
2851
- price = self.safe_string(params, 'price')
2852
- params = self.omit(params, 'price')
3055
+ priceType = self.safe_string_n(params, ['priceType', 'price'])
3056
+ params = self.omit(params, ['priceType', 'price'])
3057
+ until = None
3058
+ until, params = self.handle_param_integer(params, 'until')
3059
+ untilSeconds = self.parse_to_int(until / 1000) if (until is not None) else None
2853
3060
  if market['contract']:
2854
3061
  if limit is not None:
2855
- request['size'] = limit # when using limit from and to are ignored
3062
+ request['size'] = min(limit, 2000) # when using limit: from & to are ignored
2856
3063
  # https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
2857
3064
  else:
2858
3065
  limit = 2000 # only used for from/to calculation
2859
- if price is None:
3066
+ if priceType is None:
2860
3067
  duration = self.parse_timeframe(timeframe)
3068
+ calcualtedEnd = None
2861
3069
  if since is None:
2862
3070
  now = self.seconds()
2863
3071
  request['from'] = now - duration * (limit - 1)
2864
- request['to'] = now
3072
+ calcualtedEnd = now
2865
3073
  else:
2866
3074
  start = self.parse_to_int(since / 1000)
2867
3075
  request['from'] = start
2868
- request['to'] = self.sum(start, duration * (limit - 1))
3076
+ calcualtedEnd = self.sum(start, duration * (limit - 1))
3077
+ request['to'] = untilSeconds if (untilSeconds is not None) else calcualtedEnd
2869
3078
  response = None
2870
3079
  if market['future']:
2871
3080
  if market['inverse']:
2872
3081
  request['symbol'] = market['id']
2873
- if price == 'mark':
3082
+ if priceType == 'mark':
2874
3083
  response = self.contractPublicGetIndexMarketHistoryMarkPriceKline(self.extend(request, params))
2875
- elif price == 'index':
3084
+ elif priceType == 'index':
2876
3085
  response = self.contractPublicGetIndexMarketHistoryIndex(self.extend(request, params))
2877
- elif price == 'premiumIndex':
2878
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
3086
+ elif priceType == 'premiumIndex':
3087
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
2879
3088
  else:
2880
3089
  response = self.contractPublicGetMarketHistoryKline(self.extend(request, params))
2881
3090
  elif market['linear']:
2882
3091
  request['contract_code'] = market['id']
2883
- if price == 'mark':
3092
+ if priceType == 'mark':
2884
3093
  response = self.contractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(self.extend(request, params))
2885
- elif price == 'index':
2886
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2887
- elif price == 'premiumIndex':
3094
+ elif priceType == 'index':
3095
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
3096
+ elif priceType == 'premiumIndex':
2888
3097
  response = self.contractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(self.extend(request, params))
2889
3098
  else:
2890
3099
  response = self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
2891
3100
  elif market['swap']:
2892
3101
  request['contract_code'] = market['id']
2893
3102
  if market['inverse']:
2894
- if price == 'mark':
3103
+ if priceType == 'mark':
2895
3104
  response = self.contractPublicGetIndexMarketHistorySwapMarkPriceKline(self.extend(request, params))
2896
- elif price == 'index':
2897
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2898
- elif price == 'premiumIndex':
3105
+ elif priceType == 'index':
3106
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
3107
+ elif priceType == 'premiumIndex':
2899
3108
  response = self.contractPublicGetIndexMarketHistorySwapPremiumIndexKline(self.extend(request, params))
2900
3109
  else:
2901
3110
  response = self.contractPublicGetSwapExMarketHistoryKline(self.extend(request, params))
2902
3111
  elif market['linear']:
2903
- if price == 'mark':
3112
+ if priceType == 'mark':
2904
3113
  response = self.contractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(self.extend(request, params))
2905
- elif price == 'index':
2906
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2907
- elif price == 'premiumIndex':
3114
+ elif priceType == 'index':
3115
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
3116
+ elif priceType == 'premiumIndex':
2908
3117
  response = self.contractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(self.extend(request, params))
2909
3118
  else:
2910
3119
  response = self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
@@ -2913,15 +3122,17 @@ class htx(Exchange, ImplicitAPI):
2913
3122
  useHistorical = None
2914
3123
  useHistorical, params = self.handle_option_and_params(params, 'fetchOHLCV', 'useHistoricalEndpointForSpot', True)
2915
3124
  if not useHistorical:
2916
- # `limit` only available for the self endpoint
2917
3125
  if limit is not None:
2918
- request['size'] = limit # max 2000
3126
+ request['size'] = min(limit, 2000) # max 2000
2919
3127
  response = self.spotPublicGetMarketHistoryKline(self.extend(request, params))
2920
3128
  else:
2921
- # `since` only available for the self endpoint
3129
+ # "from & to" only available for the self endpoint
2922
3130
  if since is not None:
2923
- # default 150 bars
2924
3131
  request['from'] = self.parse_to_int(since / 1000)
3132
+ if untilSeconds is not None:
3133
+ request['to'] = untilSeconds
3134
+ if limit is not None:
3135
+ request['size'] = min(1000, limit) # max 1000, otherwise default returns 150
2925
3136
  response = self.spotPublicGetMarketHistoryCandles(self.extend(request, params))
2926
3137
  #
2927
3138
  # {
@@ -2935,12 +3146,15 @@ class htx(Exchange, ImplicitAPI):
2935
3146
  # ]
2936
3147
  # }
2937
3148
  #
2938
- data = self.safe_value(response, 'data', [])
3149
+ data = self.safe_list(response, 'data', [])
2939
3150
  return self.parse_ohlcvs(data, market, timeframe, since, limit)
2940
3151
 
2941
3152
  def fetch_accounts(self, params={}) -> List[Account]:
2942
3153
  """
2943
3154
  fetch all the accounts associated with a profile
3155
+
3156
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user
3157
+
2944
3158
  :param dict [params]: extra parameters specific to the exchange API endpoint
2945
3159
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
2946
3160
  """
@@ -2977,7 +3191,18 @@ class htx(Exchange, ImplicitAPI):
2977
3191
  'code': None,
2978
3192
  }
2979
3193
 
2980
- def fetch_account_id_by_type(self, type, marginMode=None, symbol=None, params={}):
3194
+ def fetch_account_id_by_type(self, type: str, marginMode: Str = None, symbol: Str = None, params={}):
3195
+ """
3196
+ fetch all the accounts by a type and marginModeassociated with a profile
3197
+
3198
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user
3199
+
3200
+ :param str type: 'spot', 'swap' or 'future
3201
+ :param str [marginMode]: 'cross' or 'isolated'
3202
+ :param str [symbol]: unified ccxt market symbol
3203
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3204
+ :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
3205
+ """
2981
3206
  accounts = self.load_accounts()
2982
3207
  accountId = self.safe_value_2(params, 'accountId', 'account-id')
2983
3208
  if accountId is not None:
@@ -3001,9 +3226,12 @@ class htx(Exchange, ImplicitAPI):
3001
3226
  defaultAccount = self.safe_value(accounts, 0, {})
3002
3227
  return self.safe_string(defaultAccount, 'id')
3003
3228
 
3004
- def fetch_currencies(self, params={}):
3229
+ def fetch_currencies(self, params={}) -> Currencies:
3005
3230
  """
3006
3231
  fetches all available currencies on an exchange
3232
+
3233
+ https://huobiapi.github.io/docs/spot/v1/en/#apiv2-currency-amp-chains
3234
+
3007
3235
  :param dict [params]: extra parameters specific to the exchange API endpoint
3008
3236
  :returns dict: an associative dictionary of currencies
3009
3237
  """
@@ -3046,7 +3274,7 @@ class htx(Exchange, ImplicitAPI):
3046
3274
  # }
3047
3275
  #
3048
3276
  data = self.safe_value(response, 'data', [])
3049
- result = {}
3277
+ result: dict = {}
3050
3278
  self.options['networkChainIdsByNames'] = {}
3051
3279
  self.options['networkNamesByChainIds'] = {}
3052
3280
  for i in range(0, len(data)):
@@ -3055,10 +3283,11 @@ class htx(Exchange, ImplicitAPI):
3055
3283
  code = self.safe_currency_code(currencyId)
3056
3284
  self.options['networkChainIdsByNames'][code] = {}
3057
3285
  chains = self.safe_value(entry, 'chains', [])
3058
- networks = {}
3286
+ networks: dict = {}
3059
3287
  instStatus = self.safe_string(entry, 'instStatus')
3060
3288
  currencyActive = instStatus == 'normal'
3061
3289
  minPrecision = None
3290
+ minDeposit = None
3062
3291
  minWithdraw = None
3063
3292
  maxWithdraw = None
3064
3293
  deposit = False
@@ -3070,6 +3299,7 @@ class htx(Exchange, ImplicitAPI):
3070
3299
  self.options['networkChainIdsByNames'][code][title] = uniqueChainId
3071
3300
  self.options['networkNamesByChainIds'][uniqueChainId] = title
3072
3301
  networkCode = self.network_id_to_code(uniqueChainId)
3302
+ minDeposit = self.safe_number(chainEntry, 'minDepositAmt')
3073
3303
  minWithdraw = self.safe_number(chainEntry, 'minWithdrawAmt')
3074
3304
  maxWithdraw = self.safe_number(chainEntry, 'maxWithdrawAmt')
3075
3305
  withdrawStatus = self.safe_string(chainEntry, 'withdrawStatus')
@@ -3089,7 +3319,7 @@ class htx(Exchange, ImplicitAPI):
3089
3319
  'network': networkCode,
3090
3320
  'limits': {
3091
3321
  'deposit': {
3092
- 'min': None,
3322
+ 'min': minDeposit,
3093
3323
  'max': None,
3094
3324
  },
3095
3325
  'withdraw': {
@@ -3131,7 +3361,7 @@ class htx(Exchange, ImplicitAPI):
3131
3361
  }
3132
3362
  return result
3133
3363
 
3134
- def network_id_to_code(self, networkId, currencyCode=None):
3364
+ def network_id_to_code(self, networkId: Str = None, currencyCode: Str = None):
3135
3365
  # here network-id is provided pair of currency & chain(i.e. trc20usdt)
3136
3366
  keys = list(self.options['networkNamesByChainIds'].keys())
3137
3367
  keysLength = len(keys)
@@ -3140,7 +3370,7 @@ class htx(Exchange, ImplicitAPI):
3140
3370
  networkTitle = self.safe_value(self.options['networkNamesByChainIds'], networkId, networkId)
3141
3371
  return super(htx, self).network_id_to_code(networkTitle)
3142
3372
 
3143
- def network_code_to_id(self, networkCode, currencyCode=None):
3373
+ def network_code_to_id(self, networkCode: str, currencyCode: Str = None):
3144
3374
  if currencyCode is None:
3145
3375
  raise ArgumentsRequired(self.id + ' networkCodeToId() requires a currencyCode argument')
3146
3376
  keys = list(self.options['networkChainIdsByNames'].keys())
@@ -3156,13 +3386,15 @@ class htx(Exchange, ImplicitAPI):
3156
3386
 
3157
3387
  def fetch_balance(self, params={}) -> Balances:
3158
3388
  """
3159
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-account-balance-of-a-specific-account
3160
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec4b429-7773-11ed-9966-0242ac110003
3161
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=10000074-77b7-11ed-9966-0242ac110003
3162
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-asset-valuation
3163
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-account-information
3164
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-account-information
3165
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-account-information
3389
+
3390
+ https://huobiapi.github.io/docs/spot/v1/en/#get-account-balance-of-a-specific-account
3391
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4b429-7773-11ed-9966-0242ac110003
3392
+ https://www.htx.com/en-us/opend/newApiPages/?id=10000074-77b7-11ed-9966-0242ac110003
3393
+ https://huobiapi.github.io/docs/dm/v1/en/#query-asset-valuation
3394
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-account-information
3395
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-account-information
3396
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-account-information
3397
+
3166
3398
  query for balance and get the amount of funds available for trading or funds locked in orders
3167
3399
  :param dict [params]: extra parameters specific to the exchange API endpoint
3168
3400
  :param bool [params.unified]: provide self parameter if you have a recent account with unified cross+isolated margin account
@@ -3174,7 +3406,7 @@ class htx(Exchange, ImplicitAPI):
3174
3406
  options = self.safe_value(self.options, 'fetchBalance', {})
3175
3407
  isUnifiedAccount = self.safe_value_2(params, 'isUnifiedAccount', 'unified', False)
3176
3408
  params = self.omit(params, ['isUnifiedAccount', 'unified'])
3177
- request = {}
3409
+ request: dict = {}
3178
3410
  spot = (type == 'spot')
3179
3411
  future = (type == 'future')
3180
3412
  defaultSubType = self.safe_string_2(self.options, 'defaultSubType', 'subType', 'linear')
@@ -3371,7 +3603,7 @@ class htx(Exchange, ImplicitAPI):
3371
3603
  #
3372
3604
  # TODO add balance parsing for linear swap
3373
3605
  #
3374
- result = {'info': response}
3606
+ result: dict = {'info': response}
3375
3607
  data = self.safe_value(response, 'data')
3376
3608
  if spot or margin:
3377
3609
  if isolated:
@@ -3379,7 +3611,7 @@ class htx(Exchange, ImplicitAPI):
3379
3611
  entry = data[i]
3380
3612
  symbol = self.safe_symbol(self.safe_string(entry, 'symbol'))
3381
3613
  balances = self.safe_value(entry, 'list')
3382
- subResult = {}
3614
+ subResult: dict = {}
3383
3615
  for j in range(0, len(balances)):
3384
3616
  balance = balances[j]
3385
3617
  currencyId = self.safe_string(balance, 'currency')
@@ -3404,7 +3636,7 @@ class htx(Exchange, ImplicitAPI):
3404
3636
  for j in range(0, len(isolated_swap)):
3405
3637
  balance = isolated_swap[j]
3406
3638
  marketId = self.safe_string(balance, 'contract_code')
3407
- subBalance = {
3639
+ subBalance: dict = {
3408
3640
  'code': currencyCode,
3409
3641
  'free': self.safe_number(balance, 'margin_available'),
3410
3642
  }
@@ -3434,7 +3666,7 @@ class htx(Exchange, ImplicitAPI):
3434
3666
  account = self.account()
3435
3667
  account['free'] = self.safe_string(balance, 'margin_balance')
3436
3668
  account['used'] = self.safe_string(balance, 'margin_frozen')
3437
- accountsByCode = {}
3669
+ accountsByCode: dict = {}
3438
3670
  accountsByCode[code] = account
3439
3671
  symbol = market['symbol']
3440
3672
  result[symbol] = self.safe_balance(accountsByCode)
@@ -3461,6 +3693,15 @@ class htx(Exchange, ImplicitAPI):
3461
3693
  def fetch_order(self, id: str, symbol: Str = None, params={}):
3462
3694
  """
3463
3695
  fetches information on an order made by the user
3696
+
3697
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order-based-on-client-order-id
3698
+ https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order
3699
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-information-of-an-order
3700
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-information-of-order
3701
+ https://huobiapi.github.io/docs/dm/v1/en/#get-information-of-an-order
3702
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-information-of-an-order
3703
+
3704
+ :param str id: order id
3464
3705
  :param str symbol: unified symbol of the market the order was made in
3465
3706
  :param dict [params]: extra parameters specific to the exchange API endpoint
3466
3707
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -3471,7 +3712,7 @@ class htx(Exchange, ImplicitAPI):
3471
3712
  market = self.market(symbol)
3472
3713
  marketType = None
3473
3714
  marketType, params = self.handle_market_type_and_params('fetchOrder', market, params)
3474
- request = {
3715
+ request: dict = {
3475
3716
  # spot -----------------------------------------------------------
3476
3717
  # 'order-id': 'id',
3477
3718
  # 'symbol': market['id'],
@@ -3670,7 +3911,7 @@ class htx(Exchange, ImplicitAPI):
3670
3911
  raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
3671
3912
  self.load_markets()
3672
3913
  market = None
3673
- request = {
3914
+ request: dict = {
3674
3915
  # spot_private_get_v1_order_orders GET /v1/order/orders ----------
3675
3916
  # 'symbol': market['id'], # required
3676
3917
  # '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',
@@ -3727,7 +3968,7 @@ class htx(Exchange, ImplicitAPI):
3727
3968
  # ]
3728
3969
  # }
3729
3970
  #
3730
- data = self.safe_value(response, 'data', [])
3971
+ data = self.safe_list(response, 'data', [])
3731
3972
  return self.parse_orders(data, market, since, limit)
3732
3973
 
3733
3974
  def fetch_spot_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -3741,7 +3982,7 @@ class htx(Exchange, ImplicitAPI):
3741
3982
  raise ArgumentsRequired(self.id + ' fetchContractOrders() requires a symbol argument')
3742
3983
  self.load_markets()
3743
3984
  market = self.market(symbol)
3744
- request = {
3985
+ request: dict = {
3745
3986
  # POST /api/v1/contract_hisorders inverse futures ----------------
3746
3987
  # 'symbol': market['settleId'], # BTC, ETH, ...
3747
3988
  # '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
@@ -3752,11 +3993,11 @@ class htx(Exchange, ImplicitAPI):
3752
3993
  '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
3753
3994
  }
3754
3995
  response = None
3755
- stop = self.safe_value(params, 'stop')
3996
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
3756
3997
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
3757
3998
  trailing = self.safe_bool(params, 'trailing', False)
3758
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
3759
- if stop or stopLossTakeProfit or trailing:
3999
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
4000
+ if trigger or stopLossTakeProfit or trailing:
3760
4001
  if limit is not None:
3761
4002
  request['page_size'] = limit
3762
4003
  request['contract_code'] = market['id']
@@ -3773,7 +4014,7 @@ class htx(Exchange, ImplicitAPI):
3773
4014
  marginMode, params = self.handle_margin_mode_and_params('fetchContractOrders', params)
3774
4015
  marginMode = 'cross' if (marginMode is None) else marginMode
3775
4016
  if marginMode == 'isolated':
3776
- if stop:
4017
+ if trigger:
3777
4018
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerHisorders(self.extend(request, params))
3778
4019
  elif stopLossTakeProfit:
3779
4020
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslHisorders(self.extend(request, params))
@@ -3782,7 +4023,7 @@ class htx(Exchange, ImplicitAPI):
3782
4023
  else:
3783
4024
  response = self.contractPrivatePostLinearSwapApiV3SwapHisorders(self.extend(request, params))
3784
4025
  elif marginMode == 'cross':
3785
- if stop:
4026
+ if trigger:
3786
4027
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerHisorders(self.extend(request, params))
3787
4028
  elif stopLossTakeProfit:
3788
4029
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslHisorders(self.extend(request, params))
@@ -3792,7 +4033,7 @@ class htx(Exchange, ImplicitAPI):
3792
4033
  response = self.contractPrivatePostLinearSwapApiV3SwapCrossHisorders(self.extend(request, params))
3793
4034
  elif market['inverse']:
3794
4035
  if market['swap']:
3795
- if stop:
4036
+ if trigger:
3796
4037
  response = self.contractPrivatePostSwapApiV1SwapTriggerHisorders(self.extend(request, params))
3797
4038
  elif stopLossTakeProfit:
3798
4039
  response = self.contractPrivatePostSwapApiV1SwapTpslHisorders(self.extend(request, params))
@@ -3802,7 +4043,7 @@ class htx(Exchange, ImplicitAPI):
3802
4043
  response = self.contractPrivatePostSwapApiV3SwapHisorders(self.extend(request, params))
3803
4044
  elif market['future']:
3804
4045
  request['symbol'] = market['settleId']
3805
- if stop:
4046
+ if trigger:
3806
4047
  response = self.contractPrivatePostApiV1ContractTriggerHisorders(self.extend(request, params))
3807
4048
  elif stopLossTakeProfit:
3808
4049
  response = self.contractPrivatePostApiV1ContractTpslHisorders(self.extend(request, params))
@@ -3958,25 +4199,27 @@ class htx(Exchange, ImplicitAPI):
3958
4199
  return self.parse_orders(orders, market, since, limit)
3959
4200
 
3960
4201
  def fetch_closed_contract_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3961
- request = {
4202
+ request: dict = {
3962
4203
  'status': '5,6,7', # comma separated, 0 all, 3 submitted orders, 4 partially matched, 5 partially cancelled, 6 fully matched and closed, 7 canceled
3963
4204
  }
3964
4205
  return self.fetch_contract_orders(symbol, since, limit, self.extend(request, params))
3965
4206
 
3966
4207
  def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
3967
4208
  """
3968
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
3969
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
3970
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
3971
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
3972
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
3973
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4209
+
4210
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
4211
+ https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
4212
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
4213
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
4214
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
4215
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4216
+
3974
4217
  fetches information on multiple orders made by the user
3975
4218
  :param str symbol: unified market symbol of the market orders were made in
3976
4219
  :param int [since]: the earliest time in ms to fetch orders for
3977
4220
  :param int [limit]: the maximum number of order structures to retrieve
3978
4221
  :param dict [params]: extra parameters specific to the exchange API endpoint
3979
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
4222
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
3980
4223
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
3981
4224
  :param int [params.until]: the latest time in ms to fetch entries for
3982
4225
  :param boolean [params.trailing]: *contract only* set to True if you want to fetch trailing stop orders
@@ -3998,12 +4241,14 @@ class htx(Exchange, ImplicitAPI):
3998
4241
 
3999
4242
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4000
4243
  """
4001
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
4002
- :see: https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
4003
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
4004
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
4005
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
4006
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4244
+
4245
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders
4246
+ https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours
4247
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new
4248
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new
4249
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new
4250
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new
4251
+
4007
4252
  fetches information on multiple closed orders made by the user
4008
4253
  :param str symbol: unified market symbol of the market orders were made in
4009
4254
  :param int [since]: the earliest time in ms to fetch orders for
@@ -4030,15 +4275,17 @@ class htx(Exchange, ImplicitAPI):
4030
4275
 
4031
4276
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4032
4277
  """
4033
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-open-orders
4034
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-current-unfilled-order-acquisition
4035
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-current-unfilled-order-acquisition
4278
+
4279
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-open-orders
4280
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-current-unfilled-order-acquisition
4281
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-current-unfilled-order-acquisition
4282
+
4036
4283
  fetch all unfilled currently open orders
4037
4284
  :param str symbol: unified market symbol
4038
4285
  :param int [since]: the earliest time in ms to fetch open orders for
4039
4286
  :param int [limit]: the maximum number of open order structures to retrieve
4040
4287
  :param dict [params]: extra parameters specific to the exchange API endpoint
4041
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
4288
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
4042
4289
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
4043
4290
  :param boolean [params.trailing]: *contract only* set to True if you want to fetch trailing stop orders
4044
4291
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -4047,7 +4294,7 @@ class htx(Exchange, ImplicitAPI):
4047
4294
  market = None
4048
4295
  if symbol is not None:
4049
4296
  market = self.market(symbol)
4050
- request = {}
4297
+ request: dict = {}
4051
4298
  marketType = None
4052
4299
  marketType, params = self.handle_market_type_and_params('fetchOpenOrders', market, params)
4053
4300
  response = None
@@ -4061,7 +4308,7 @@ class htx(Exchange, ImplicitAPI):
4061
4308
  self.load_accounts()
4062
4309
  for i in range(0, len(self.accounts)):
4063
4310
  account = self.accounts[i]
4064
- if account['type'] == 'spot':
4311
+ if self.safe_string(account, 'type') == 'spot':
4065
4312
  accountId = self.safe_string(account, 'id')
4066
4313
  if accountId is not None:
4067
4314
  break
@@ -4076,16 +4323,16 @@ class htx(Exchange, ImplicitAPI):
4076
4323
  if limit is not None:
4077
4324
  request['page_size'] = limit
4078
4325
  request['contract_code'] = market['id']
4079
- stop = self.safe_value(params, 'stop')
4326
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
4080
4327
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4081
4328
  trailing = self.safe_bool(params, 'trailing', False)
4082
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
4329
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
4083
4330
  if market['linear']:
4084
4331
  marginMode = None
4085
4332
  marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
4086
4333
  marginMode = 'cross' if (marginMode is None) else marginMode
4087
4334
  if marginMode == 'isolated':
4088
- if stop:
4335
+ if trigger:
4089
4336
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerOpenorders(self.extend(request, params))
4090
4337
  elif stopLossTakeProfit:
4091
4338
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslOpenorders(self.extend(request, params))
@@ -4094,7 +4341,7 @@ class htx(Exchange, ImplicitAPI):
4094
4341
  else:
4095
4342
  response = self.contractPrivatePostLinearSwapApiV1SwapOpenorders(self.extend(request, params))
4096
4343
  elif marginMode == 'cross':
4097
- if stop:
4344
+ if trigger:
4098
4345
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOpenorders(self.extend(request, params))
4099
4346
  elif stopLossTakeProfit:
4100
4347
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOpenorders(self.extend(request, params))
@@ -4104,7 +4351,7 @@ class htx(Exchange, ImplicitAPI):
4104
4351
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossOpenorders(self.extend(request, params))
4105
4352
  elif market['inverse']:
4106
4353
  if market['swap']:
4107
- if stop:
4354
+ if trigger:
4108
4355
  response = self.contractPrivatePostSwapApiV1SwapTriggerOpenorders(self.extend(request, params))
4109
4356
  elif stopLossTakeProfit:
4110
4357
  response = self.contractPrivatePostSwapApiV1SwapTpslOpenorders(self.extend(request, params))
@@ -4114,7 +4361,7 @@ class htx(Exchange, ImplicitAPI):
4114
4361
  response = self.contractPrivatePostSwapApiV1SwapOpenorders(self.extend(request, params))
4115
4362
  elif market['future']:
4116
4363
  request['symbol'] = market['settleId']
4117
- if stop:
4364
+ if trigger:
4118
4365
  response = self.contractPrivatePostApiV1ContractTriggerOpenorders(self.extend(request, params))
4119
4366
  elif stopLossTakeProfit:
4120
4367
  response = self.contractPrivatePostApiV1ContractTpslOpenorders(self.extend(request, params))
@@ -4311,8 +4558,8 @@ class htx(Exchange, ImplicitAPI):
4311
4558
  orders = self.safe_value(orders, 'orders', [])
4312
4559
  return self.parse_orders(orders, market, since, limit)
4313
4560
 
4314
- def parse_order_status(self, status):
4315
- statuses = {
4561
+ def parse_order_status(self, status: Str):
4562
+ statuses: dict = {
4316
4563
  # spot
4317
4564
  'partial-filled': 'open',
4318
4565
  'partial-canceled': 'canceled',
@@ -4332,7 +4579,7 @@ class htx(Exchange, ImplicitAPI):
4332
4579
  }
4333
4580
  return self.safe_string(statuses, status, status)
4334
4581
 
4335
- def parse_order(self, order, market: Market = None) -> Order:
4582
+ def parse_order(self, order: dict, market: Market = None) -> Order:
4336
4583
  #
4337
4584
  # spot
4338
4585
  #
@@ -4709,14 +4956,10 @@ class htx(Exchange, ImplicitAPI):
4709
4956
  cost = None
4710
4957
  amount = None
4711
4958
  if (type is not None) and (type.find('market') >= 0):
4712
- # for market orders amount is in quote currency, meaning it is the cost
4713
- if side == 'sell':
4714
- cost = self.safe_string(order, 'field-cash-amount')
4715
- else:
4716
- cost = self.safe_string(order, 'amount')
4959
+ cost = self.safe_string(order, 'field-cash-amount')
4717
4960
  else:
4718
4961
  amount = self.safe_string_2(order, 'volume', 'amount')
4719
- cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo
4962
+ cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo here
4720
4963
  filled = self.safe_string_n(order, ['filled-amount', 'field-amount', 'trade_volume']) # typo in their API, filled amount
4721
4964
  price = self.safe_string_2(order, 'price', 'order_price')
4722
4965
  feeCost = self.safe_string_2(order, 'filled-fees', 'field-fees') # typo in their API, filled feeSide
@@ -4733,7 +4976,6 @@ class htx(Exchange, ImplicitAPI):
4733
4976
  'cost': feeCost,
4734
4977
  'currency': feeCurrency,
4735
4978
  }
4736
- stopPrice = self.safe_string_2(order, 'stop-price', 'trigger_price')
4737
4979
  average = self.safe_string(order, 'trade_avg_price')
4738
4980
  trades = self.safe_value(order, 'trades')
4739
4981
  reduceOnlyInteger = self.safe_integer(order, 'reduce_only')
@@ -4753,8 +4995,7 @@ class htx(Exchange, ImplicitAPI):
4753
4995
  'postOnly': None,
4754
4996
  'side': side,
4755
4997
  'price': price,
4756
- 'stopPrice': stopPrice,
4757
- 'triggerPrice': stopPrice,
4998
+ 'triggerPrice': self.safe_string_2(order, 'stop-price', 'trigger_price'),
4758
4999
  'average': average,
4759
5000
  'cost': cost,
4760
5001
  'amount': amount,
@@ -4769,7 +5010,9 @@ class htx(Exchange, ImplicitAPI):
4769
5010
  def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
4770
5011
  """
4771
5012
  create a market buy order by providing the symbol and cost
4772
- :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
5013
+
5014
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
5015
+
4773
5016
  :param str symbol: unified symbol of the market to create an order in
4774
5017
  :param float cost: how much you want to trade in units of the quote currency
4775
5018
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4805,13 +5048,13 @@ class htx(Exchange, ImplicitAPI):
4805
5048
 
4806
5049
  def create_spot_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
4807
5050
  """
4808
- * @ignore
5051
+ @ignore
4809
5052
  helper function to build request
4810
5053
  :param str symbol: unified symbol of the market to create an order in
4811
5054
  :param str type: 'market' or 'limit'
4812
5055
  :param str side: 'buy' or 'sell'
4813
5056
  :param float amount: how much you want to trade in units of the base currency
4814
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5057
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4815
5058
  :param dict [params]: extra parameters specific to the exchange API endpoint
4816
5059
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4817
5060
  :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
@@ -4823,7 +5066,7 @@ class htx(Exchange, ImplicitAPI):
4823
5066
  marginMode = None
4824
5067
  marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
4825
5068
  accountId = self.fetch_account_id_by_type(market['type'], marginMode, symbol)
4826
- request = {
5069
+ request: dict = {
4827
5070
  # spot -----------------------------------------------------------
4828
5071
  'account-id': accountId,
4829
5072
  'symbol': market['id'],
@@ -4838,15 +5081,15 @@ class htx(Exchange, ImplicitAPI):
4838
5081
  orderType = type.replace('buy-', '')
4839
5082
  orderType = orderType.replace('sell-', '')
4840
5083
  options = self.safe_value(self.options, market['type'], {})
4841
- stopPrice = self.safe_string_2(params, 'stopPrice', 'stop-price')
4842
- if stopPrice is None:
5084
+ triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'stop-price'])
5085
+ if triggerPrice is None:
4843
5086
  stopOrderTypes = self.safe_value(options, 'stopOrderTypes', {})
4844
5087
  if orderType in stopOrderTypes:
4845
- raise ArgumentsRequired(self.id + ' createOrder() requires a stopPrice or a stop-price parameter for a stop order')
5088
+ raise ArgumentsRequired(self.id + ' createOrder() requires a triggerPrice for a trigger order')
4846
5089
  else:
4847
5090
  defaultOperator = 'lte' if (side == 'sell') else 'gte'
4848
5091
  stopOperator = self.safe_string(params, 'operator', defaultOperator)
4849
- request['stop-price'] = self.price_to_precision(symbol, stopPrice)
5092
+ request['stop-price'] = self.price_to_precision(symbol, triggerPrice)
4850
5093
  request['operator'] = stopOperator
4851
5094
  if (orderType == 'limit') or (orderType == 'limit-fok'):
4852
5095
  orderType = 'stop-' + orderType
@@ -4904,18 +5147,18 @@ class htx(Exchange, ImplicitAPI):
4904
5147
  limitOrderTypes = self.safe_value(options, 'limitOrderTypes', {})
4905
5148
  if orderType in limitOrderTypes:
4906
5149
  request['price'] = self.price_to_precision(symbol, price)
4907
- params = self.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
5150
+ params = self.omit(params, ['triggerPrice', 'stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
4908
5151
  return self.extend(request, params)
4909
5152
 
4910
5153
  def create_contract_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
4911
5154
  """
4912
- * @ignore
5155
+ @ignore
4913
5156
  helper function to build request
4914
5157
  :param str symbol: unified symbol of the market to create an order in
4915
5158
  :param str type: 'market' or 'limit'
4916
5159
  :param str side: 'buy' or 'sell'
4917
5160
  :param float amount: how much you want to trade in units of the base currency
4918
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5161
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4919
5162
  :param dict [params]: extra parameters specific to the exchange API endpoint
4920
5163
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4921
5164
  :param float [params.trailingPercent]: *contract only* the percent to trail away from the current market price
@@ -4923,7 +5166,7 @@ class htx(Exchange, ImplicitAPI):
4923
5166
  :returns dict: request to be sent to the exchange
4924
5167
  """
4925
5168
  market = self.market(symbol)
4926
- request = {
5169
+ request: dict = {
4927
5170
  'contract_code': market['id'],
4928
5171
  'volume': self.amount_to_precision(symbol, amount),
4929
5172
  'direction': side,
@@ -4937,16 +5180,16 @@ class htx(Exchange, ImplicitAPI):
4937
5180
  type = 'fok'
4938
5181
  elif timeInForce == 'IOC':
4939
5182
  type = 'ioc'
4940
- triggerPrice = self.safe_number_2(params, 'stopPrice', 'trigger_price')
5183
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
4941
5184
  stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
4942
5185
  takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
4943
5186
  trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callback_rate')
4944
5187
  trailingTriggerPrice = self.safe_number(params, 'trailingTriggerPrice', price)
4945
5188
  isTrailingPercentOrder = trailingPercent is not None
4946
- isStop = triggerPrice is not None
5189
+ isTrigger = triggerPrice is not None
4947
5190
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
4948
5191
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
4949
- if isStop:
5192
+ if isTrigger:
4950
5193
  triggerType = self.safe_string_2(params, 'triggerType', 'trigger_type', 'le')
4951
5194
  request['trigger_type'] = triggerType
4952
5195
  request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
@@ -4975,59 +5218,70 @@ class htx(Exchange, ImplicitAPI):
4975
5218
  params = self.omit(params, ['clientOrderId'])
4976
5219
  if type == 'limit' or type == 'ioc' or type == 'fok' or type == 'post_only':
4977
5220
  request['price'] = self.price_to_precision(symbol, price)
5221
+ reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only', False)
4978
5222
  if not isStopLossTriggerOrder and not isTakeProfitTriggerOrder:
4979
- reduceOnly = self.safe_value_2(params, 'reduceOnly', 'reduce_only', False)
4980
5223
  if reduceOnly:
4981
5224
  request['reduce_only'] = 1
4982
5225
  request['lever_rate'] = self.safe_integer_n(params, ['leverRate', 'lever_rate', 'leverage'], 1)
4983
5226
  if not isTrailingPercentOrder:
4984
5227
  request['order_price_type'] = type
5228
+ hedged = self.safe_bool(params, 'hedged', False)
5229
+ if hedged:
5230
+ if reduceOnly:
5231
+ request['offset'] = 'close'
5232
+ else:
5233
+ request['offset'] = 'open'
4985
5234
  broker = self.safe_value(self.options, 'broker', {})
4986
5235
  brokerId = self.safe_string(broker, 'id')
4987
5236
  request['channel_code'] = brokerId
4988
- params = self.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
5237
+ params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice', 'hedged'])
4989
5238
  return self.extend(request, params)
4990
5239
 
4991
5240
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
4992
5241
  """
4993
5242
  create a trade order
4994
- :see: https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order # spot, margin
4995
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order # coin-m swap
4996
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order # coin-m swap trigger
4997
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order # usdt-m swap cross
4998
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order # usdt-m swap cross trigger
4999
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order # usdt-m swap isolated
5000
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order # usdt-m swap isolated trigger
5001
- :see: https://huobiapi.github.io/docs/dm/v1/en/#place-an-order # coin-m futures
5002
- :see: https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order # coin-m futures contract trigger
5243
+
5244
+ https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order # spot, margin
5245
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order # coin-m swap
5246
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order # coin-m swap trigger
5247
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order # usdt-m swap cross
5248
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order # usdt-m swap cross trigger
5249
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order # usdt-m swap isolated
5250
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order # usdt-m swap isolated trigger
5251
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-set-a-take-profit-and-stop-loss-order-for-an-existing-position
5252
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-set-a-take-profit-and-stop-loss-order-for-an-existing-position
5253
+ https://huobiapi.github.io/docs/dm/v1/en/#place-an-order # coin-m futures
5254
+ https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order # coin-m futures contract trigger
5255
+
5003
5256
  :param str symbol: unified symbol of the market to create an order in
5004
5257
  :param str type: 'market' or 'limit'
5005
5258
  :param str side: 'buy' or 'sell'
5006
5259
  :param float amount: how much you want to trade in units of the base currency
5007
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5260
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
5008
5261
  :param dict [params]: extra parameters specific to the exchange API endpoint
5009
- :param float [params.stopPrice]: the price a trigger order is triggered at
5262
+ :param float [params.triggerPrice]: the price a trigger order is triggered at
5010
5263
  :param str [params.triggerType]: *contract trigger orders only* ge: greater than or equal to, le: less than or equal to
5011
5264
  :param float [params.stopLossPrice]: *contract only* the price a stop-loss order is triggered at
5012
5265
  :param float [params.takeProfitPrice]: *contract only* the price a take-profit order is triggered at
5013
5266
  :param str [params.operator]: *spot and margin only* gte or lte, trigger price condition
5014
- :param str [params.offset]: *contract only* 'open', 'close', or 'both', required in hedge mode
5267
+ :param str [params.offset]: *contract only* 'both'(linear only), 'open', or 'close', required in hedge mode and for inverse markets
5015
5268
  :param bool [params.postOnly]: *contract only* True or False
5016
5269
  :param int [params.leverRate]: *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
5017
5270
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
5018
5271
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
5019
5272
  :param float [params.trailingPercent]: *contract only* the percent to trail away from the current market price
5020
5273
  :param float [params.trailingTriggerPrice]: *contract only* the price to trigger a trailing order, default uses the price argument
5274
+ :param bool [params.hedged]: *contract only* True for hedged mode, False for one way mode, default is False
5021
5275
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
5022
5276
  """
5023
5277
  self.load_markets()
5024
5278
  market = self.market(symbol)
5025
- triggerPrice = self.safe_number_2(params, 'stopPrice', 'trigger_price')
5279
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
5026
5280
  stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
5027
5281
  takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
5028
5282
  trailingPercent = self.safe_number(params, 'trailingPercent')
5029
5283
  isTrailingPercentOrder = trailingPercent is not None
5030
- isStop = triggerPrice is not None
5284
+ isTrigger = triggerPrice is not None
5031
5285
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
5032
5286
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
5033
5287
  response = None
@@ -5043,7 +5297,7 @@ class htx(Exchange, ImplicitAPI):
5043
5297
  marginMode, contractRequest = self.handle_margin_mode_and_params('createOrder', contractRequest)
5044
5298
  marginMode = 'cross' if (marginMode is None) else marginMode
5045
5299
  if marginMode == 'isolated':
5046
- if isStop:
5300
+ if isTrigger:
5047
5301
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerOrder(contractRequest)
5048
5302
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5049
5303
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslOrder(contractRequest)
@@ -5052,7 +5306,7 @@ class htx(Exchange, ImplicitAPI):
5052
5306
  else:
5053
5307
  response = self.contractPrivatePostLinearSwapApiV1SwapOrder(contractRequest)
5054
5308
  elif marginMode == 'cross':
5055
- if isStop:
5309
+ if isTrigger:
5056
5310
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(contractRequest)
5057
5311
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5058
5312
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(contractRequest)
@@ -5061,8 +5315,11 @@ class htx(Exchange, ImplicitAPI):
5061
5315
  else:
5062
5316
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossOrder(contractRequest)
5063
5317
  elif market['inverse']:
5318
+ offset = self.safe_string(params, 'offset')
5319
+ if offset is None:
5320
+ raise ArgumentsRequired(self.id + ' createOrder() requires an extra parameter params["offset"] to be set to "open" or "close" when placing orders in inverse markets')
5064
5321
  if market['swap']:
5065
- if isStop:
5322
+ if isTrigger:
5066
5323
  response = self.contractPrivatePostSwapApiV1SwapTriggerOrder(contractRequest)
5067
5324
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5068
5325
  response = self.contractPrivatePostSwapApiV1SwapTpslOrder(contractRequest)
@@ -5071,7 +5328,7 @@ class htx(Exchange, ImplicitAPI):
5071
5328
  else:
5072
5329
  response = self.contractPrivatePostSwapApiV1SwapOrder(contractRequest)
5073
5330
  elif market['future']:
5074
- if isStop:
5331
+ if isTrigger:
5075
5332
  response = self.contractPrivatePostApiV1ContractTriggerOrder(contractRequest)
5076
5333
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5077
5334
  response = self.contractPrivatePostApiV1ContractTpslOrder(contractRequest)
@@ -5145,11 +5402,13 @@ class htx(Exchange, ImplicitAPI):
5145
5402
  def create_orders(self, orders: List[OrderRequest], params={}):
5146
5403
  """
5147
5404
  create a list of trade orders
5148
- :see: https://huobiapi.github.io/docs/spot/v1/en/#place-a-batch-of-orders
5149
- :see: https://huobiapi.github.io/docs/dm/v1/en/#place-a-batch-of-orders
5150
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-a-batch-of-orders
5151
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-a-batch-of-orders
5152
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-a-batch-of-orders
5405
+
5406
+ https://huobiapi.github.io/docs/spot/v1/en/#place-a-batch-of-orders
5407
+ https://huobiapi.github.io/docs/dm/v1/en/#place-a-batch-of-orders
5408
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-a-batch-of-orders
5409
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-a-batch-of-orders
5410
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-a-batch-of-orders
5411
+
5153
5412
  :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
5154
5413
  :param dict [params]: extra parameters specific to the exchange API endpoint
5155
5414
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5188,7 +5447,7 @@ class htx(Exchange, ImplicitAPI):
5188
5447
  orderRequest = self.create_contract_order_request(marketId, type, side, amount, price, orderParams)
5189
5448
  orderRequest = self.omit(orderRequest, 'marginMode')
5190
5449
  ordersRequests.append(orderRequest)
5191
- request = {}
5450
+ request: dict = {}
5192
5451
  response = None
5193
5452
  if market['spot']:
5194
5453
  response = self.privatePostOrderBatchOrders(ordersRequests)
@@ -5262,7 +5521,7 @@ class htx(Exchange, ImplicitAPI):
5262
5521
  :param str id: order id
5263
5522
  :param str symbol: unified symbol of the market the order was made in
5264
5523
  :param dict [params]: extra parameters specific to the exchange API endpoint
5265
- :param boolean [params.stop]: *contract only* if the order is a stop trigger order or not
5524
+ :param boolean [params.trigger]: *contract only* if the order is a trigger trigger order or not
5266
5525
  :param boolean [params.stopLossTakeProfit]: *contract only* if the order is a stop-loss or take-profit order
5267
5526
  :param boolean [params.trailing]: *contract only* set to True if you want to cancel a trailing order
5268
5527
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5273,7 +5532,7 @@ class htx(Exchange, ImplicitAPI):
5273
5532
  market = self.market(symbol)
5274
5533
  marketType = None
5275
5534
  marketType, params = self.handle_market_type_and_params('cancelOrder', market, params)
5276
- request = {
5535
+ request: dict = {
5277
5536
  # spot -----------------------------------------------------------
5278
5537
  # 'order-id': 'id',
5279
5538
  # 'symbol': market['id'],
@@ -5308,16 +5567,16 @@ class htx(Exchange, ImplicitAPI):
5308
5567
  request['symbol'] = market['settleId']
5309
5568
  else:
5310
5569
  request['contract_code'] = market['id']
5311
- stop = self.safe_value(params, 'stop')
5570
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5312
5571
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5313
5572
  trailing = self.safe_bool(params, 'trailing', False)
5314
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
5573
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
5315
5574
  if market['linear']:
5316
5575
  marginMode = None
5317
5576
  marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
5318
5577
  marginMode = 'cross' if (marginMode is None) else marginMode
5319
5578
  if marginMode == 'isolated':
5320
- if stop:
5579
+ if trigger:
5321
5580
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
5322
5581
  elif stopLossTakeProfit:
5323
5582
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
@@ -5326,7 +5585,7 @@ class htx(Exchange, ImplicitAPI):
5326
5585
  else:
5327
5586
  response = self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
5328
5587
  elif marginMode == 'cross':
5329
- if stop:
5588
+ if trigger:
5330
5589
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
5331
5590
  elif stopLossTakeProfit:
5332
5591
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
@@ -5336,7 +5595,7 @@ class htx(Exchange, ImplicitAPI):
5336
5595
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
5337
5596
  elif market['inverse']:
5338
5597
  if market['swap']:
5339
- if stop:
5598
+ if trigger:
5340
5599
  response = self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
5341
5600
  elif stopLossTakeProfit:
5342
5601
  response = self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
@@ -5345,7 +5604,7 @@ class htx(Exchange, ImplicitAPI):
5345
5604
  else:
5346
5605
  response = self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
5347
5606
  elif market['future']:
5348
- if stop:
5607
+ if trigger:
5349
5608
  response = self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
5350
5609
  elif stopLossTakeProfit:
5351
5610
  response = self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
@@ -5385,7 +5644,7 @@ class htx(Exchange, ImplicitAPI):
5385
5644
  :param str[] ids: order ids
5386
5645
  :param str symbol: unified market symbol, default is None
5387
5646
  :param dict [params]: extra parameters specific to the exchange API endpoint
5388
- :param bool [params.stop]: *contract only* if the orders are stop trigger orders or not
5647
+ :param bool [params.trigger]: *contract only* if the orders are trigger trigger orders or not
5389
5648
  :param bool [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
5390
5649
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5391
5650
  """
@@ -5395,7 +5654,7 @@ class htx(Exchange, ImplicitAPI):
5395
5654
  market = self.market(symbol)
5396
5655
  marketType = None
5397
5656
  marketType, params = self.handle_market_type_and_params('cancelOrders', market, params)
5398
- request = {
5657
+ request: dict = {
5399
5658
  # spot -----------------------------------------------------------
5400
5659
  # 'order-ids': ','.join(ids), # max 50
5401
5660
  # 'client-order-ids': ','.join(ids), # max 50
@@ -5435,22 +5694,22 @@ class htx(Exchange, ImplicitAPI):
5435
5694
  request['symbol'] = market['settleId']
5436
5695
  else:
5437
5696
  request['contract_code'] = market['id']
5438
- stop = self.safe_value(params, 'stop')
5697
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5439
5698
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5440
- params = self.omit(params, ['stop', 'stopLossTakeProfit'])
5699
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trigger'])
5441
5700
  if market['linear']:
5442
5701
  marginMode = None
5443
5702
  marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
5444
5703
  marginMode = 'cross' if (marginMode is None) else marginMode
5445
5704
  if marginMode == 'isolated':
5446
- if stop:
5705
+ if trigger:
5447
5706
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
5448
5707
  elif stopLossTakeProfit:
5449
5708
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
5450
5709
  else:
5451
5710
  response = self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
5452
5711
  elif marginMode == 'cross':
5453
- if stop:
5712
+ if trigger:
5454
5713
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
5455
5714
  elif stopLossTakeProfit:
5456
5715
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
@@ -5458,14 +5717,14 @@ class htx(Exchange, ImplicitAPI):
5458
5717
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
5459
5718
  elif market['inverse']:
5460
5719
  if market['swap']:
5461
- if stop:
5720
+ if trigger:
5462
5721
  response = self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
5463
5722
  elif stopLossTakeProfit:
5464
5723
  response = self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
5465
5724
  else:
5466
5725
  response = self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
5467
5726
  elif market['future']:
5468
- if stop:
5727
+ if trigger:
5469
5728
  response = self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
5470
5729
  elif stopLossTakeProfit:
5471
5730
  response = self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
@@ -5524,14 +5783,69 @@ class htx(Exchange, ImplicitAPI):
5524
5783
  # "ts": 1604367997451
5525
5784
  # }
5526
5785
  #
5527
- return response
5786
+ data = self.safe_dict(response, 'data')
5787
+ return self.parse_cancel_orders(data)
5788
+
5789
+ def parse_cancel_orders(self, orders):
5790
+ #
5791
+ # {
5792
+ # "success": [
5793
+ # "5983466"
5794
+ # ],
5795
+ # "failed": [
5796
+ # {
5797
+ # "err-msg": "Incorrect order state",
5798
+ # "order-state": 7,
5799
+ # "order-id": "",
5800
+ # "err-code": "order-orderstate-error",
5801
+ # "client-order-id": "first"
5802
+ # },
5803
+ # ...
5804
+ # ]
5805
+ # }
5806
+ #
5807
+ # {
5808
+ # "errors": [
5809
+ # {
5810
+ # "order_id": "769206471845261312",
5811
+ # "err_code": 1061,
5812
+ # "err_msg": "This order doesnt exist."
5813
+ # }
5814
+ # ],
5815
+ # "successes": "1258075374411399168,1258075393254871040"
5816
+ # }
5817
+ #
5818
+ successes = self.safe_string(orders, 'successes')
5819
+ success = None
5820
+ if successes is not None:
5821
+ success = successes.split(',')
5822
+ else:
5823
+ success = self.safe_list(orders, 'success', [])
5824
+ failed = self.safe_list_2(orders, 'errors', 'failed', [])
5825
+ result = []
5826
+ for i in range(0, len(success)):
5827
+ order = success[i]
5828
+ result.append(self.safe_order({
5829
+ 'info': order,
5830
+ 'id': order,
5831
+ 'status': 'canceled',
5832
+ }))
5833
+ for i in range(0, len(failed)):
5834
+ order = failed[i]
5835
+ result.append(self.safe_order({
5836
+ 'info': order,
5837
+ 'id': self.safe_string_2(order, 'order-id', 'order_id'),
5838
+ 'status': 'failed',
5839
+ 'clientOrderId': self.safe_string(order, 'client-order-id'),
5840
+ }))
5841
+ return result
5528
5842
 
5529
5843
  def cancel_all_orders(self, symbol: Str = None, params={}):
5530
5844
  """
5531
5845
  cancel all open orders
5532
5846
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
5533
5847
  :param dict [params]: extra parameters specific to the exchange API endpoint
5534
- :param boolean [params.stop]: *contract only* if the orders are stop trigger orders or not
5848
+ :param boolean [params.trigger]: *contract only* if the orders are trigger trigger orders or not
5535
5849
  :param boolean [params.stopLossTakeProfit]: *contract only* if the orders are stop-loss or take-profit orders
5536
5850
  :param boolean [params.trailing]: *contract only* set to True if you want to cancel all trailing orders
5537
5851
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -5542,7 +5856,7 @@ class htx(Exchange, ImplicitAPI):
5542
5856
  market = self.market(symbol)
5543
5857
  marketType = None
5544
5858
  marketType, params = self.handle_market_type_and_params('cancelAllOrders', market, params)
5545
- request = {
5859
+ request: dict = {
5546
5860
  # spot -----------------------------------------------------------
5547
5861
  # 'account-id': account['id'],
5548
5862
  # 'symbol': market['id'], # a list of comma-separated symbols, all symbols by default
@@ -5561,22 +5875,38 @@ class htx(Exchange, ImplicitAPI):
5561
5875
  if symbol is not None:
5562
5876
  request['symbol'] = market['id']
5563
5877
  response = self.spotPrivatePostV1OrderOrdersBatchCancelOpenOrders(self.extend(request, params))
5878
+ #
5879
+ # {
5880
+ # "code": 200,
5881
+ # "data": {
5882
+ # "success-count": 2,
5883
+ # "failed-count": 0,
5884
+ # "next-id": 5454600
5885
+ # }
5886
+ # }
5887
+ #
5888
+ data = self.safe_dict(response, 'data')
5889
+ return [
5890
+ self.safe_order({
5891
+ 'info': data,
5892
+ }),
5893
+ ]
5564
5894
  else:
5565
5895
  if symbol is None:
5566
5896
  raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
5567
5897
  if market['future']:
5568
5898
  request['symbol'] = market['settleId']
5569
5899
  request['contract_code'] = market['id']
5570
- stop = self.safe_value(params, 'stop')
5900
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5571
5901
  stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
5572
5902
  trailing = self.safe_bool(params, 'trailing', False)
5573
- params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing'])
5903
+ params = self.omit(params, ['stop', 'stopLossTakeProfit', 'trailing', 'trigger'])
5574
5904
  if market['linear']:
5575
5905
  marginMode = None
5576
5906
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
5577
5907
  marginMode = 'cross' if (marginMode is None) else marginMode
5578
5908
  if marginMode == 'isolated':
5579
- if stop:
5909
+ if trigger:
5580
5910
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerCancelall(self.extend(request, params))
5581
5911
  elif stopLossTakeProfit:
5582
5912
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslCancelall(self.extend(request, params))
@@ -5585,7 +5915,7 @@ class htx(Exchange, ImplicitAPI):
5585
5915
  else:
5586
5916
  response = self.contractPrivatePostLinearSwapApiV1SwapCancelall(self.extend(request, params))
5587
5917
  elif marginMode == 'cross':
5588
- if stop:
5918
+ if trigger:
5589
5919
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancelall(self.extend(request, params))
5590
5920
  elif stopLossTakeProfit:
5591
5921
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancelall(self.extend(request, params))
@@ -5595,7 +5925,7 @@ class htx(Exchange, ImplicitAPI):
5595
5925
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossCancelall(self.extend(request, params))
5596
5926
  elif market['inverse']:
5597
5927
  if market['swap']:
5598
- if stop:
5928
+ if trigger:
5599
5929
  response = self.contractPrivatePostSwapApiV1SwapTriggerCancelall(self.extend(request, params))
5600
5930
  elif stopLossTakeProfit:
5601
5931
  response = self.contractPrivatePostSwapApiV1SwapTpslCancelall(self.extend(request, params))
@@ -5604,7 +5934,7 @@ class htx(Exchange, ImplicitAPI):
5604
5934
  else:
5605
5935
  response = self.contractPrivatePostSwapApiV1SwapCancelall(self.extend(request, params))
5606
5936
  elif market['future']:
5607
- if stop:
5937
+ if trigger:
5608
5938
  response = self.contractPrivatePostApiV1ContractTriggerCancelall(self.extend(request, params))
5609
5939
  elif stopLossTakeProfit:
5610
5940
  response = self.contractPrivatePostApiV1ContractTpslCancelall(self.extend(request, params))
@@ -5614,29 +5944,44 @@ class htx(Exchange, ImplicitAPI):
5614
5944
  response = self.contractPrivatePostApiV1ContractCancelall(self.extend(request, params))
5615
5945
  else:
5616
5946
  raise NotSupported(self.id + ' cancelAllOrders() does not support ' + marketType + ' markets')
5617
- #
5618
- # spot
5947
+ #
5948
+ # {
5949
+ # "status": "ok",
5950
+ # "data": {
5951
+ # "errors": [],
5952
+ # "successes": "1104754904426696704"
5953
+ # },
5954
+ # "ts": "1683435723755"
5955
+ # }
5956
+ #
5957
+ data = self.safe_dict(response, 'data')
5958
+ return self.parse_cancel_orders(data)
5959
+
5960
+ def cancel_all_orders_after(self, timeout: Int, params={}):
5961
+ """
5962
+ dead man's switch, cancel all orders after the given timeout
5963
+
5964
+ https://huobiapi.github.io/docs/spot/v1/en/#dead-man-s-switch
5965
+
5966
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
5967
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5968
+ :returns dict: the api result
5969
+ """
5970
+ self.load_markets()
5971
+ request: dict = {
5972
+ 'timeout': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
5973
+ }
5974
+ response = self.v2PrivatePostAlgoOrdersCancelAllAfter(self.extend(request, params))
5619
5975
  #
5620
5976
  # {
5621
5977
  # "code": 200,
5978
+ # "message": "success",
5622
5979
  # "data": {
5623
- # "success-count": 2,
5624
- # "failed-count": 0,
5625
- # "next-id": 5454600
5980
+ # "currentTime": 1630491627230,
5981
+ # "triggerTime": 1630491637230
5626
5982
  # }
5627
5983
  # }
5628
5984
  #
5629
- # future and swap
5630
- #
5631
- # {
5632
- # "status": "ok",
5633
- # "data": {
5634
- # "errors": [],
5635
- # "successes": "1104754904426696704"
5636
- # },
5637
- # "ts": "1683435723755"
5638
- # }
5639
- #
5640
5985
  return response
5641
5986
 
5642
5987
  def parse_deposit_address(self, depositAddress, currency: Currency = None):
@@ -5665,8 +6010,11 @@ class htx(Exchange, ImplicitAPI):
5665
6010
  'info': depositAddress,
5666
6011
  }
5667
6012
 
5668
- def fetch_deposit_addresses_by_network(self, code: str, params={}):
6013
+ def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
5669
6014
  """
6015
+
6016
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec50029-7773-11ed-9966-0242ac110003
6017
+
5670
6018
  fetch a dictionary of addresses for a currency, indexed by network
5671
6019
  :param str code: unified currency code of the currency for the deposit address
5672
6020
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5674,7 +6022,7 @@ class htx(Exchange, ImplicitAPI):
5674
6022
  """
5675
6023
  self.load_markets()
5676
6024
  currency = self.currency(code)
5677
- request = {
6025
+ request: dict = {
5678
6026
  'currency': currency['id'],
5679
6027
  }
5680
6028
  response = self.spotPrivateGetV2AccountDepositAddress(self.extend(request, params))
@@ -5695,9 +6043,12 @@ class htx(Exchange, ImplicitAPI):
5695
6043
  parsed = self.parse_deposit_addresses(data, [currency['code']], False)
5696
6044
  return self.index_by(parsed, 'network')
5697
6045
 
5698
- def fetch_deposit_address(self, code: str, params={}):
6046
+ def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
5699
6047
  """
5700
6048
  fetch the deposit address for a currency associated with self account
6049
+
6050
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec50029-7773-11ed-9966-0242ac110003
6051
+
5701
6052
  :param str code: unified currency code
5702
6053
  :param dict [params]: extra parameters specific to the exchange API endpoint
5703
6054
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -5712,7 +6063,7 @@ class htx(Exchange, ImplicitAPI):
5712
6063
  def fetch_withdraw_addresses(self, code: str, note=None, networkCode=None, params={}):
5713
6064
  self.load_markets()
5714
6065
  currency = self.currency(code)
5715
- request = {
6066
+ request: dict = {
5716
6067
  'currency': currency['id'],
5717
6068
  }
5718
6069
  response = self.spotPrivateGetV2AccountWithdrawAddress(self.extend(request, params))
@@ -5743,6 +6094,9 @@ class htx(Exchange, ImplicitAPI):
5743
6094
 
5744
6095
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
5745
6096
  """
6097
+
6098
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4f050-7773-11ed-9966-0242ac110003
6099
+
5746
6100
  fetch all deposits made to an account
5747
6101
  :param str code: unified currency code
5748
6102
  :param int [since]: the earliest time in ms to fetch deposits for
@@ -5756,7 +6110,7 @@ class htx(Exchange, ImplicitAPI):
5756
6110
  currency = None
5757
6111
  if code is not None:
5758
6112
  currency = self.currency(code)
5759
- request = {
6113
+ request: dict = {
5760
6114
  'type': 'deposit',
5761
6115
  'direct': 'next',
5762
6116
  'from': 0, # From 'id' ... if you want to get results after a particular transaction id, pass the id in params.from
@@ -5797,6 +6151,9 @@ class htx(Exchange, ImplicitAPI):
5797
6151
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
5798
6152
  """
5799
6153
  fetch all withdrawals made from an account
6154
+
6155
+ https://huobiapi.github.io/docs/spot/v1/en/#search-for-existed-withdraws-and-deposits
6156
+
5800
6157
  :param str code: unified currency code
5801
6158
  :param int [since]: the earliest time in ms to fetch withdrawals for
5802
6159
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -5809,7 +6166,7 @@ class htx(Exchange, ImplicitAPI):
5809
6166
  currency = None
5810
6167
  if code is not None:
5811
6168
  currency = self.currency(code)
5812
- request = {
6169
+ request: dict = {
5813
6170
  'type': 'withdraw',
5814
6171
  'direct': 'next',
5815
6172
  'from': 0, # From 'id' ... if you want to get results after a particular transaction id, pass the id in params.from
@@ -5845,7 +6202,7 @@ class htx(Exchange, ImplicitAPI):
5845
6202
  #
5846
6203
  return self.parse_transactions(response['data'], currency, since, limit)
5847
6204
 
5848
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
6205
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
5849
6206
  #
5850
6207
  # fetchDeposits
5851
6208
  #
@@ -5937,8 +6294,8 @@ class htx(Exchange, ImplicitAPI):
5937
6294
  },
5938
6295
  }
5939
6296
 
5940
- def parse_transaction_status(self, status):
5941
- statuses = {
6297
+ def parse_transaction_status(self, status: Str):
6298
+ statuses: dict = {
5942
6299
  # deposit statuses
5943
6300
  'unknown': 'failed',
5944
6301
  'confirming': 'pending',
@@ -5960,8 +6317,11 @@ class htx(Exchange, ImplicitAPI):
5960
6317
  }
5961
6318
  return self.safe_string(statuses, status, status)
5962
6319
 
5963
- def withdraw(self, code: str, amount: float, address, tag=None, params={}):
6320
+ def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
5964
6321
  """
6322
+
6323
+ https://www.htx.com/en-us/opend/newApiPages/?id=7ec4cc41-7773-11ed-9966-0242ac110003
6324
+
5965
6325
  make a withdrawal
5966
6326
  :param str code: unified currency code
5967
6327
  :param float amount: the amount to withdraw
@@ -5974,7 +6334,7 @@ class htx(Exchange, ImplicitAPI):
5974
6334
  self.load_markets()
5975
6335
  self.check_address(address)
5976
6336
  currency = self.currency(code)
5977
- request = {
6337
+ request: dict = {
5978
6338
  'address': address, # only supports existing addresses in your withdraw address list
5979
6339
  'currency': currency['id'].lower(),
5980
6340
  }
@@ -6013,7 +6373,7 @@ class htx(Exchange, ImplicitAPI):
6013
6373
  #
6014
6374
  return self.parse_transaction(response, currency)
6015
6375
 
6016
- def parse_transfer(self, transfer, currency: Currency = None):
6376
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
6017
6377
  #
6018
6378
  # transfer
6019
6379
  #
@@ -6039,13 +6399,15 @@ class htx(Exchange, ImplicitAPI):
6039
6399
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
6040
6400
  """
6041
6401
  transfer currency internally between wallets on the same account
6042
- :see: https://huobiapi.github.io/docs/dm/v1/en/#transfer-margin-between-spot-account-and-future-account
6043
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-fund-between-spot-account-and-future-contract-account
6044
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-transfer-margin-between-spot-account-and-usdt-margined-contracts-account
6045
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-cross-margin-account-cross
6046
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-isolated-margin-account-isolated
6047
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-cross-margin-account-to-spot-trading-account-cross
6048
- :see: https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-isolated-margin-account-to-spot-trading-account-isolated
6402
+
6403
+ https://huobiapi.github.io/docs/dm/v1/en/#transfer-margin-between-spot-account-and-future-account
6404
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-fund-between-spot-account-and-future-contract-account
6405
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-transfer-margin-between-spot-account-and-usdt-margined-contracts-account
6406
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-cross-margin-account-cross
6407
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-isolated-margin-account-isolated
6408
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-cross-margin-account-to-spot-trading-account-cross
6409
+ https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-isolated-margin-account-to-spot-trading-account-isolated
6410
+
6049
6411
  :param str code: unified currency code
6050
6412
  :param float amount: amount to transfer
6051
6413
  :param str fromAccount: account to transfer from 'spot', 'future', 'swap'
@@ -6057,7 +6419,7 @@ class htx(Exchange, ImplicitAPI):
6057
6419
  """
6058
6420
  self.load_markets()
6059
6421
  currency = self.currency(code)
6060
- request = {
6422
+ request: dict = {
6061
6423
  'currency': currency['id'],
6062
6424
  'amount': float(self.currency_to_precision(code, amount)),
6063
6425
  }
@@ -6118,9 +6480,12 @@ class htx(Exchange, ImplicitAPI):
6118
6480
  #
6119
6481
  return self.parse_transfer(response, currency)
6120
6482
 
6121
- def fetch_isolated_borrow_rates(self, params={}):
6483
+ def fetch_isolated_borrow_rates(self, params={}) -> IsolatedBorrowRates:
6122
6484
  """
6123
6485
  fetch the borrow interest rates of all currencies
6486
+
6487
+ https://huobiapi.github.io/docs/spot/v1/en/#get-loan-interest-rate-and-quota-isolated
6488
+
6124
6489
  :param dict [params]: extra parameters specific to the exchange API endpoint
6125
6490
  :returns dict: a list of `isolated borrow rate structures <https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure>`
6126
6491
  """
@@ -6156,12 +6521,9 @@ class htx(Exchange, ImplicitAPI):
6156
6521
  # }
6157
6522
  #
6158
6523
  data = self.safe_value(response, 'data', [])
6159
- rates = []
6160
- for i in range(0, len(data)):
6161
- rates.append(self.parse_isolated_borrow_rate(data[i]))
6162
- return rates
6524
+ return self.parse_isolated_borrow_rates(data)
6163
6525
 
6164
- def parse_isolated_borrow_rate(self, info, market: Market = None):
6526
+ def parse_isolated_borrow_rate(self, info: dict, market: Market = None) -> IsolatedBorrowRate:
6165
6527
  #
6166
6528
  # {
6167
6529
  # "symbol": "1inchusdt",
@@ -6206,8 +6568,10 @@ class htx(Exchange, ImplicitAPI):
6206
6568
 
6207
6569
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6208
6570
  """
6209
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-funding-rate
6210
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-funding-rate
6571
+
6572
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-funding-rate
6573
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-funding-rate
6574
+
6211
6575
  fetches historical funding rate prices
6212
6576
  :param str symbol: unified symbol of the market to fetch the funding rate history for
6213
6577
  :param int [since]: not used by huobi, but filtered internally by ccxt
@@ -6224,7 +6588,7 @@ class htx(Exchange, ImplicitAPI):
6224
6588
  return self.fetch_paginated_call_cursor('fetchFundingRateHistory', symbol, since, limit, params, 'page_index', 'current_page', 1, 50)
6225
6589
  self.load_markets()
6226
6590
  market = self.market(symbol)
6227
- request = {
6591
+ request: dict = {
6228
6592
  'contract_code': market['id'],
6229
6593
  }
6230
6594
  response = None
@@ -6276,7 +6640,7 @@ class htx(Exchange, ImplicitAPI):
6276
6640
  sorted = self.sort_by(rates, 'timestamp')
6277
6641
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
6278
6642
 
6279
- def parse_funding_rate(self, contract, market: Market = None):
6643
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
6280
6644
  #
6281
6645
  # {
6282
6646
  # "status": "ok",
@@ -6295,6 +6659,9 @@ class htx(Exchange, ImplicitAPI):
6295
6659
  nextFundingRate = self.safe_number(contract, 'estimated_rate')
6296
6660
  fundingTimestamp = self.safe_integer(contract, 'funding_time')
6297
6661
  nextFundingTimestamp = self.safe_integer(contract, 'next_funding_time')
6662
+ fundingTimeString = self.safe_string(contract, 'funding_time')
6663
+ nextFundingTimeString = self.safe_string(contract, 'next_funding_time')
6664
+ millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
6298
6665
  marketId = self.safe_string(contract, 'contract_code')
6299
6666
  symbol = self.safe_symbol(marketId, market)
6300
6667
  return {
@@ -6315,18 +6682,33 @@ class htx(Exchange, ImplicitAPI):
6315
6682
  'previousFundingRate': None,
6316
6683
  'previousFundingTimestamp': None,
6317
6684
  'previousFundingDatetime': None,
6685
+ 'interval': self.parse_funding_interval(millisecondsInterval),
6318
6686
  }
6319
6687
 
6320
- def fetch_funding_rate(self, symbol: str, params={}):
6688
+ def parse_funding_interval(self, interval):
6689
+ intervals: dict = {
6690
+ '3600000': '1h',
6691
+ '14400000': '4h',
6692
+ '28800000': '8h',
6693
+ '57600000': '16h',
6694
+ '86400000': '24h',
6695
+ }
6696
+ return self.safe_string(intervals, interval, interval)
6697
+
6698
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
6321
6699
  """
6322
6700
  fetch the current funding rate
6701
+
6702
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-funding-rate
6703
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-funding-rate
6704
+
6323
6705
  :param str symbol: unified market symbol
6324
6706
  :param dict [params]: extra parameters specific to the exchange API endpoint
6325
6707
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
6326
6708
  """
6327
6709
  self.load_markets()
6328
6710
  market = self.market(symbol)
6329
- request = {
6711
+ request: dict = {
6330
6712
  'contract_code': market['id'],
6331
6713
  }
6332
6714
  response = None
@@ -6354,12 +6736,16 @@ class htx(Exchange, ImplicitAPI):
6354
6736
  result = self.safe_value(response, 'data', {})
6355
6737
  return self.parse_funding_rate(result, market)
6356
6738
 
6357
- def fetch_funding_rates(self, symbols: Strings = None, params={}):
6739
+ def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6358
6740
  """
6359
6741
  fetch the funding rate for multiple markets
6742
+
6743
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-funding-rate
6744
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-funding-rate
6745
+
6360
6746
  :param str[]|None symbols: list of unified market symbols
6361
6747
  :param dict [params]: extra parameters specific to the exchange API endpoint
6362
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
6748
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
6363
6749
  """
6364
6750
  self.load_markets()
6365
6751
  symbols = self.market_symbols(symbols)
@@ -6367,7 +6753,7 @@ class htx(Exchange, ImplicitAPI):
6367
6753
  defaultSubType = self.safe_string(self.options, 'defaultSubType', 'inverse')
6368
6754
  subType = self.safe_string(options, 'subType', defaultSubType)
6369
6755
  subType = self.safe_string(params, 'subType', subType)
6370
- request = {
6756
+ request: dict = {
6371
6757
  # 'contract_code': market['id'],
6372
6758
  }
6373
6759
  params = self.omit(params, 'subType')
@@ -6397,12 +6783,15 @@ class htx(Exchange, ImplicitAPI):
6397
6783
  # }
6398
6784
  #
6399
6785
  data = self.safe_value(response, 'data', [])
6400
- result = self.parse_funding_rates(data)
6401
- return self.filter_by_array(result, 'symbol', symbols)
6786
+ return self.parse_funding_rates(data, symbols)
6402
6787
 
6403
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6788
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6404
6789
  """
6405
6790
  fetch the interest owed by the user for borrowing currency for margin trading
6791
+
6792
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-cross
6793
+ https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-isolated
6794
+
6406
6795
  :param str code: unified currency code
6407
6796
  :param str symbol: unified market symbol when fetch interest in isolated markets
6408
6797
  :param int [since]: the earliest time in ms to fetch borrrow interest for
@@ -6414,7 +6803,7 @@ class htx(Exchange, ImplicitAPI):
6414
6803
  marginMode = None
6415
6804
  marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params)
6416
6805
  marginMode = 'cross' if (marginMode is None) else marginMode
6417
- request = {}
6806
+ request: dict = {}
6418
6807
  if since is not None:
6419
6808
  request['start-date'] = self.yyyymmdd(since)
6420
6809
  if limit is not None:
@@ -6457,7 +6846,7 @@ class htx(Exchange, ImplicitAPI):
6457
6846
  interest = self.parse_borrow_interests(data, market)
6458
6847
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6459
6848
 
6460
- def parse_borrow_interest(self, info, market: Market = None):
6849
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6461
6850
  # isolated
6462
6851
  # {
6463
6852
  # "interest-rate":"0.000040830000000000",
@@ -6505,18 +6894,20 @@ class htx(Exchange, ImplicitAPI):
6505
6894
  symbol = self.safe_string(market, 'symbol')
6506
6895
  timestamp = self.safe_integer(info, 'accrued-at')
6507
6896
  return {
6508
- 'account': symbol if (marginMode == 'isolated') else 'cross', # deprecated
6897
+ 'info': info,
6509
6898
  'symbol': symbol,
6510
- 'marginMode': marginMode,
6511
6899
  'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6512
6900
  'interest': self.safe_number(info, 'interest-amount'),
6513
6901
  'interestRate': self.safe_number(info, 'interest-rate'),
6514
6902
  'amountBorrowed': self.safe_number(info, 'loan-amount'),
6903
+ 'marginMode': marginMode,
6515
6904
  'timestamp': timestamp, # Interest accrued time
6516
6905
  'datetime': self.iso8601(timestamp),
6517
- 'info': info,
6518
6906
  }
6519
6907
 
6908
+ def nonce(self):
6909
+ return self.milliseconds() - self.options['timeDifference']
6910
+
6520
6911
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
6521
6912
  url = '/'
6522
6913
  query = self.omit(params, self.extract_params(path))
@@ -6529,8 +6920,8 @@ class htx(Exchange, ImplicitAPI):
6529
6920
  url += '/' + self.implode_params(path, params)
6530
6921
  if api == 'private' or api == 'v2Private':
6531
6922
  self.check_required_credentials()
6532
- timestamp = self.ymdhms(self.milliseconds(), 'T')
6533
- request = {
6923
+ timestamp = self.ymdhms(self.nonce(), 'T')
6924
+ request: dict = {
6534
6925
  'SignatureMethod': 'HmacSHA256',
6535
6926
  'SignatureVersion': '2',
6536
6927
  'AccessKeyId': self.apiKey,
@@ -6593,8 +6984,8 @@ class htx(Exchange, ImplicitAPI):
6593
6984
  clientOrderId = self.safe_string(params, 'client-order-id')
6594
6985
  if clientOrderId is None:
6595
6986
  params['client-order-id'] = id + self.uuid()
6596
- timestamp = self.ymdhms(self.milliseconds(), 'T')
6597
- request = {
6987
+ timestamp = self.ymdhms(self.nonce(), 'T')
6988
+ request: dict = {
6598
6989
  'SignatureMethod': 'HmacSHA256',
6599
6990
  'SignatureVersion': '2',
6600
6991
  'AccessKeyId': self.apiKey,
@@ -6625,7 +7016,7 @@ class htx(Exchange, ImplicitAPI):
6625
7016
  }) + url
6626
7017
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
6627
7018
 
6628
- def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
7019
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
6629
7020
  if response is None:
6630
7021
  return None # fallback to default error handler
6631
7022
  if 'status' in response:
@@ -6651,9 +7042,11 @@ class htx(Exchange, ImplicitAPI):
6651
7042
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6652
7043
  """
6653
7044
  fetch the history of funding payments paid and received on self account
6654
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-account-financial-records-via-multiple-fields-new # linear swaps
6655
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-financial-records-via-multiple-fields-new # coin-m futures
6656
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-financial-records-via-multiple-fields-new # coin-m swaps
7045
+
7046
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-account-financial-records-via-multiple-fields-new # linear swaps
7047
+ https://huobiapi.github.io/docs/dm/v1/en/#query-financial-records-via-multiple-fields-new # coin-m futures
7048
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-financial-records-via-multiple-fields-new # coin-m swaps
7049
+
6657
7050
  :param str symbol: unified market symbol
6658
7051
  :param int [since]: the earliest time in ms to fetch funding history for
6659
7052
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -6663,7 +7056,7 @@ class htx(Exchange, ImplicitAPI):
6663
7056
  self.load_markets()
6664
7057
  market = self.market(symbol)
6665
7058
  marketType, query = self.handle_market_type_and_params('fetchFundingHistory', market, params)
6666
- request = {
7059
+ request: dict = {
6667
7060
  'type': '30,31',
6668
7061
  }
6669
7062
  if since is not None:
@@ -6727,12 +7120,18 @@ class htx(Exchange, ImplicitAPI):
6727
7120
  else:
6728
7121
  request['symbol'] = market['id']
6729
7122
  response = self.contractPrivatePostApiV3ContractFinancialRecordExact(self.extend(request, query))
6730
- data = self.safe_value(response, 'data', [])
7123
+ data = self.safe_list(response, 'data', [])
6731
7124
  return self.parse_incomes(data, market, since, limit)
6732
7125
 
6733
7126
  def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
6734
7127
  """
6735
7128
  set the level of leverage for a market
7129
+
7130
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-leverage
7131
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-leverage
7132
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#switch-leverage
7133
+ https://huobiapi.github.io/docs/dm/v1/en/#switch-leverage # Coin-m futures
7134
+
6736
7135
  :param float leverage: the rate of leverage
6737
7136
  :param str symbol: unified market symbol
6738
7137
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6743,7 +7142,7 @@ class htx(Exchange, ImplicitAPI):
6743
7142
  self.load_markets()
6744
7143
  market = self.market(symbol)
6745
7144
  marketType, query = self.handle_market_type_and_params('setLeverage', market, params)
6746
- request = {
7145
+ request: dict = {
6747
7146
  'lever_rate': leverage,
6748
7147
  }
6749
7148
  if marketType == 'future' and market['inverse']:
@@ -6825,7 +7224,7 @@ class htx(Exchange, ImplicitAPI):
6825
7224
  'amount': amount,
6826
7225
  }
6827
7226
 
6828
- def parse_position(self, position, market: Market = None):
7227
+ def parse_position(self, position: dict, market: Market = None):
6829
7228
  #
6830
7229
  # {
6831
7230
  # "symbol": "BTC",
@@ -6894,7 +7293,7 @@ class htx(Exchange, ImplicitAPI):
6894
7293
  'entryPrice': entryPrice,
6895
7294
  'collateral': self.parse_number(collateral),
6896
7295
  'side': side,
6897
- 'unrealizedProfit': unrealizedProfit,
7296
+ 'unrealizedPnl': unrealizedProfit,
6898
7297
  'leverage': self.parse_number(leverage),
6899
7298
  'percentage': self.parse_number(percentage),
6900
7299
  'marginMode': marginMode,
@@ -6918,16 +7317,27 @@ class htx(Exchange, ImplicitAPI):
6918
7317
  def fetch_positions(self, symbols: Strings = None, params={}):
6919
7318
  """
6920
7319
  fetch all open positions
6921
- :param str[]|None symbols: list of unified market symbols
7320
+
7321
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-position-information
7322
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-position-information
7323
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-position-information
7324
+ https://huobiapi.github.io/docs/dm/v1/en/#query-user-s-position-information
7325
+
7326
+ :param str[] [symbols]: list of unified market symbols
6922
7327
  :param dict [params]: extra parameters specific to the exchange API endpoint
7328
+ :param str [params.subType]: 'linear' or 'inverse'
7329
+ :param str [params.type]: *inverse only* 'future', or 'swap'
7330
+ :param str [params.marginMode]: *linear only* 'cross' or 'isolated'
6923
7331
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
6924
7332
  """
6925
7333
  self.load_markets()
6926
7334
  symbols = self.market_symbols(symbols)
6927
7335
  market = None
6928
7336
  if symbols is not None:
6929
- first = self.safe_string(symbols, 0)
6930
- market = self.market(first)
7337
+ symbolsLength = len(symbols)
7338
+ if symbolsLength > 0:
7339
+ first = self.safe_string(symbols, 0)
7340
+ market = self.market(first)
6931
7341
  marginMode = None
6932
7342
  marginMode, params = self.handle_margin_mode_and_params('fetchPositions', params, 'cross')
6933
7343
  subType = None
@@ -7043,6 +7453,12 @@ class htx(Exchange, ImplicitAPI):
7043
7453
  def fetch_position(self, symbol: str, params={}):
7044
7454
  """
7045
7455
  fetch data on a single open contract trade position
7456
+
7457
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-assets-and-positions
7458
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-assets-and-positions
7459
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-assets-and-positions
7460
+ https://huobiapi.github.io/docs/dm/v1/en/#query-assets-and-positions
7461
+
7046
7462
  :param str symbol: unified market symbol of the market the position is held in, default is None
7047
7463
  :param dict [params]: extra parameters specific to the exchange API endpoint
7048
7464
  :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
@@ -7053,7 +7469,7 @@ class htx(Exchange, ImplicitAPI):
7053
7469
  marginMode, params = self.handle_margin_mode_and_params('fetchPosition', params)
7054
7470
  marginMode = 'cross' if (marginMode is None) else marginMode
7055
7471
  marketType, query = self.handle_market_type_and_params('fetchPosition', market, params)
7056
- request = {}
7472
+ request: dict = {}
7057
7473
  if market['future'] and market['inverse']:
7058
7474
  request['symbol'] = market['settleId']
7059
7475
  else:
@@ -7285,7 +7701,7 @@ class htx(Exchange, ImplicitAPI):
7285
7701
  return parsed
7286
7702
 
7287
7703
  def parse_ledger_entry_type(self, type):
7288
- types = {
7704
+ types: dict = {
7289
7705
  'trade': 'trade',
7290
7706
  'etf': 'trade',
7291
7707
  'transact-fee': 'fee',
@@ -7303,7 +7719,7 @@ class htx(Exchange, ImplicitAPI):
7303
7719
  }
7304
7720
  return self.safe_string(types, type, type)
7305
7721
 
7306
- def parse_ledger_entry(self, item, currency: Currency = None):
7722
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
7307
7723
  #
7308
7724
  # {
7309
7725
  # "accountId": 10000001,
@@ -7317,45 +7733,44 @@ class htx(Exchange, ImplicitAPI):
7317
7733
  # "transferee": 13496526
7318
7734
  # }
7319
7735
  #
7320
- id = self.safe_string(item, 'transactId')
7321
7736
  currencyId = self.safe_string(item, 'currency')
7322
7737
  code = self.safe_currency_code(currencyId, currency)
7323
- amount = self.safe_number(item, 'transactAmt')
7738
+ currency = self.safe_currency(currencyId, currency)
7739
+ id = self.safe_string(item, 'transactId')
7324
7740
  transferType = self.safe_string(item, 'transferType')
7325
- type = self.parse_ledger_entry_type(transferType)
7326
- direction = self.safe_string(item, 'direction')
7327
7741
  timestamp = self.safe_integer(item, 'transactTime')
7328
- datetime = self.iso8601(timestamp)
7329
7742
  account = self.safe_string(item, 'accountId')
7330
- return {
7743
+ return self.safe_ledger_entry({
7744
+ 'info': item,
7331
7745
  'id': id,
7332
- 'direction': direction,
7746
+ 'direction': self.safe_string(item, 'direction'),
7333
7747
  'account': account,
7334
7748
  'referenceId': id,
7335
7749
  'referenceAccount': account,
7336
- 'type': type,
7750
+ 'type': self.parse_ledger_entry_type(transferType),
7337
7751
  'currency': code,
7338
- 'amount': amount,
7752
+ 'amount': self.safe_number(item, 'transactAmt'),
7339
7753
  'timestamp': timestamp,
7340
- 'datetime': datetime,
7754
+ 'datetime': self.iso8601(timestamp),
7341
7755
  'before': None,
7342
7756
  'after': None,
7343
7757
  'status': None,
7344
7758
  'fee': None,
7345
- 'info': item,
7346
- }
7759
+ }, currency)
7347
7760
 
7348
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
7761
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
7349
7762
  """
7350
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-account-history
7351
- fetch the history of changes, actions done by the user or operations that altered balance of the user
7352
- :param str code: unified currency code, default is None
7763
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
7764
+
7765
+ https://huobiapi.github.io/docs/spot/v1/en/#get-account-history
7766
+
7767
+ :param str [code]: unified currency code, default is None
7353
7768
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
7354
- :param int [limit]: max number of ledger entrys to return, default is None
7769
+ :param int [limit]: max number of ledger entries to return, default is None
7355
7770
  :param dict [params]: extra parameters specific to the exchange API endpoint
7356
7771
  :param int [params.until]: the latest time in ms to fetch entries for
7357
- :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)
7358
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
7772
+ :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)
7773
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
7359
7774
  """
7360
7775
  self.load_markets()
7361
7776
  paginate = False
@@ -7363,7 +7778,7 @@ class htx(Exchange, ImplicitAPI):
7363
7778
  if paginate:
7364
7779
  return self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params, 500)
7365
7780
  accountId = self.fetch_account_id_by_type('spot', None, None, params)
7366
- request = {
7781
+ request: dict = {
7367
7782
  'accountId': accountId,
7368
7783
  # 'currency': code,
7369
7784
  # 'transactTypes': 'all', # default all
@@ -7418,7 +7833,7 @@ class htx(Exchange, ImplicitAPI):
7418
7833
  data = self.safe_value(response, 'data', [])
7419
7834
  return self.parse_ledger(data, currency, since, limit)
7420
7835
 
7421
- def fetch_leverage_tiers(self, symbols: Strings = None, params={}):
7836
+ def fetch_leverage_tiers(self, symbols: Strings = None, params={}) -> LeverageTiers:
7422
7837
  """
7423
7838
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
7424
7839
  :param str[]|None symbols: list of unified market symbols
@@ -7456,92 +7871,41 @@ class htx(Exchange, ImplicitAPI):
7456
7871
  # ]
7457
7872
  # }
7458
7873
  #
7459
- data = self.safe_value(response, 'data')
7874
+ data = self.safe_list(response, 'data', [])
7460
7875
  return self.parse_leverage_tiers(data, symbols, 'contract_code')
7461
7876
 
7462
- def fetch_market_leverage_tiers(self, symbol: str, params={}):
7463
- """
7464
- retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
7465
- :param str symbol: unified market symbol
7466
- :param dict [params]: extra parameters specific to the exchange API endpoint
7467
- :returns dict: a `leverage tiers structure <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`
7468
- """
7469
- self.load_markets()
7470
- request = {}
7471
- if symbol is not None:
7472
- market = self.market(symbol)
7473
- if not market['contract']:
7474
- raise BadRequest(self.id + ' fetchMarketLeverageTiers() symbol supports contract markets only')
7475
- request['contract_code'] = market['id']
7476
- response = self.contractPublicGetLinearSwapApiV1SwapAdjustfactor(self.extend(request, params))
7477
- #
7478
- # {
7479
- # "status": "ok",
7480
- # "data": [
7481
- # {
7482
- # "symbol": "MANA",
7483
- # "contract_code": "MANA-USDT",
7484
- # "margin_mode": "isolated",
7485
- # "trade_partition": "USDT",
7486
- # "list": [
7487
- # {
7488
- # "lever_rate": 75,
7489
- # "ladders": [
7490
- # {
7491
- # "ladder": 0,
7492
- # "min_size": 0,
7493
- # "max_size": 999,
7494
- # "adjust_factor": 0.7
7495
- # },
7496
- # ...
7497
- # ]
7498
- # }
7499
- # ...
7500
- # ]
7501
- # },
7502
- # ...
7503
- # ]
7504
- # }
7505
- #
7506
- data = self.safe_value(response, 'data')
7507
- tiers = self.parse_leverage_tiers(data, [symbol], 'contract_code')
7508
- return self.safe_value(tiers, symbol)
7509
-
7510
- def parse_leverage_tiers(self, response, symbols: Strings = None, marketIdKey=None):
7511
- result = {}
7512
- for i in range(0, len(response)):
7513
- item = response[i]
7514
- list = self.safe_value(item, 'list', [])
7515
- tiers = []
7516
- currency = self.safe_string(item, 'trade_partition')
7517
- id = self.safe_string(item, marketIdKey)
7518
- symbol = self.safe_symbol(id)
7519
- if self.in_array(symbol, symbols):
7520
- for j in range(0, len(list)):
7521
- obj = list[j]
7522
- leverage = self.safe_string(obj, 'lever_rate')
7523
- ladders = self.safe_value(obj, 'ladders', [])
7524
- for k in range(0, len(ladders)):
7525
- bracket = ladders[k]
7526
- adjustFactor = self.safe_string(bracket, 'adjust_factor')
7527
- tiers.append({
7528
- 'tier': self.safe_integer(bracket, 'ladder'),
7529
- 'currency': self.safe_currency_code(currency),
7530
- 'minNotional': self.safe_number(bracket, 'min_size'),
7531
- 'maxNotional': self.safe_number(bracket, 'max_size'),
7532
- 'maintenanceMarginRate': self.parse_number(Precise.string_div(adjustFactor, leverage)),
7533
- 'maxLeverage': self.parse_number(leverage),
7534
- 'info': bracket,
7535
- })
7536
- result[symbol] = tiers
7537
- return result
7877
+ def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
7878
+ currencyId = self.safe_string(info, 'trade_partition')
7879
+ marketId = self.safe_string(info, 'contract_code')
7880
+ tiers = []
7881
+ brackets = self.safe_list(info, 'list', [])
7882
+ for i in range(0, len(brackets)):
7883
+ item = brackets[i]
7884
+ leverage = self.safe_string(item, 'lever_rate')
7885
+ ladders = self.safe_list(item, 'ladders', [])
7886
+ for k in range(0, len(ladders)):
7887
+ bracket = ladders[k]
7888
+ adjustFactor = self.safe_string(bracket, 'adjust_factor')
7889
+ tiers.append({
7890
+ 'tier': self.safe_integer(bracket, 'ladder'),
7891
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
7892
+ 'currency': self.safe_currency_code(currencyId),
7893
+ 'minNotional': self.safe_number(bracket, 'min_size'),
7894
+ 'maxNotional': self.safe_number(bracket, 'max_size'),
7895
+ 'maintenanceMarginRate': self.parse_number(Precise.string_div(adjustFactor, leverage)),
7896
+ 'maxLeverage': self.parse_number(leverage),
7897
+ 'info': bracket,
7898
+ })
7899
+ return tiers
7538
7900
 
7539
7901
  def fetch_open_interest_history(self, symbol: str, timeframe='1h', since: Int = None, limit: Int = None, params={}):
7540
7902
  """
7541
7903
  Retrieves the open interest history of a currency
7542
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-information-on-open-interest
7543
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-information-on-open-interest
7544
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-information-on-open-interest
7904
+
7905
+ https://huobiapi.github.io/docs/dm/v1/en/#query-information-on-open-interest
7906
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-information-on-open-interest
7907
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-information-on-open-interest
7908
+
7545
7909
  :param str symbol: Unified CCXT market symbol
7546
7910
  :param str timeframe: '1h', '4h', '12h', or '1d'
7547
7911
  :param int [since]: Not used by huobi api, but response parsed by CCXT
@@ -7554,7 +7918,7 @@ class htx(Exchange, ImplicitAPI):
7554
7918
  if timeframe != '1h' and timeframe != '4h' and timeframe != '12h' and timeframe != '1d':
7555
7919
  raise BadRequest(self.id + ' fetchOpenInterestHistory cannot only use the 1h, 4h, 12h and 1d timeframe')
7556
7920
  self.load_markets()
7557
- timeframes = {
7921
+ timeframes: dict = {
7558
7922
  '1h': '60min',
7559
7923
  '4h': '4hour',
7560
7924
  '12h': '12hour',
@@ -7562,7 +7926,7 @@ class htx(Exchange, ImplicitAPI):
7562
7926
  }
7563
7927
  market = self.market(symbol)
7564
7928
  amountType = self.safe_integer_2(params, 'amount_type', 'amountType', 2)
7565
- request = {
7929
+ request: dict = {
7566
7930
  'period': timeframes[timeframe],
7567
7931
  'amount_type': amountType,
7568
7932
  }
@@ -7645,15 +8009,110 @@ class htx(Exchange, ImplicitAPI):
7645
8009
  # }
7646
8010
  #
7647
8011
  data = self.safe_value(response, 'data')
7648
- tick = self.safe_value(data, 'tick')
7649
- return self.parse_open_interests(tick, market, since, limit)
8012
+ tick = self.safe_list(data, 'tick')
8013
+ return self.parse_open_interests_history(tick, market, since, limit)
8014
+
8015
+ def fetch_open_interests(self, symbols: Strings = None, params={}):
8016
+ """
8017
+ Retrieves the open interest for a list of symbols
8018
+
8019
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information
8020
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information
8021
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information
8022
+
8023
+ :param str[] [symbols]: a list of unified CCXT market symbols
8024
+ :param dict [params]: exchange specific parameters
8025
+ :returns dict[]: a list of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
8026
+ """
8027
+ self.load_markets()
8028
+ symbols = self.market_symbols(symbols)
8029
+ market = None
8030
+ if symbols is not None:
8031
+ symbolsLength = len(symbols)
8032
+ if symbolsLength > 0:
8033
+ first = self.safe_string(symbols, 0)
8034
+ market = self.market(first)
8035
+ request: dict = {}
8036
+ subType = None
8037
+ subType, params = self.handle_sub_type_and_params('fetchPositions', market, params, 'linear')
8038
+ marketType = None
8039
+ marketType, params = self.handle_market_type_and_params('fetchPositions', market, params)
8040
+ response = None
8041
+ if marketType == 'future':
8042
+ response = self.contractPublicGetApiV1ContractOpenInterest(self.extend(request, params))
8043
+ #
8044
+ # {
8045
+ # "status": "ok",
8046
+ # "data": [
8047
+ # {
8048
+ # "volume": 118850.000000000000000000,
8049
+ # "amount": 635.502025211544374189,
8050
+ # "symbol": "BTC",
8051
+ # "contract_type": "self_week",
8052
+ # "contract_code": "BTC220930",
8053
+ # "trade_amount": 1470.9400749347598691119206024033947897351,
8054
+ # "trade_volume": 286286,
8055
+ # "trade_turnover": 28628600.000000000000000000
8056
+ # }
8057
+ # ],
8058
+ # "ts": 1664337928805
8059
+ # }
8060
+ #
8061
+ elif subType == 'inverse':
8062
+ response = self.contractPublicGetSwapApiV1SwapOpenInterest(self.extend(request, params))
8063
+ #
8064
+ # {
8065
+ # "status": "ok",
8066
+ # "data": [
8067
+ # {
8068
+ # "volume": 518018.000000000000000000,
8069
+ # "amount": 2769.675777407074725180,
8070
+ # "symbol": "BTC",
8071
+ # "contract_code": "BTC-USD",
8072
+ # "trade_amount": 9544.4032080046491323463688602729806842458,
8073
+ # "trade_volume": 1848448,
8074
+ # "trade_turnover": 184844800.000000000000000000
8075
+ # }
8076
+ # ],
8077
+ # "ts": 1664337226028
8078
+ # }
8079
+ #
8080
+ else:
8081
+ request['contract_type'] = 'swap'
8082
+ response = self.contractPublicGetLinearSwapApiV1SwapOpenInterest(self.extend(request, params))
8083
+ #
8084
+ # {
8085
+ # "status": "ok",
8086
+ # "data": [
8087
+ # {
8088
+ # "volume": 7192610.000000000000000000,
8089
+ # "amount": 7192.610000000000000000,
8090
+ # "symbol": "BTC",
8091
+ # "value": 134654290.332000000000000000,
8092
+ # "contract_code": "BTC-USDT",
8093
+ # "trade_amount": 70692.804,
8094
+ # "trade_volume": 70692804,
8095
+ # "trade_turnover": 1379302592.9518,
8096
+ # "business_type": "swap",
8097
+ # "pair": "BTC-USDT",
8098
+ # "contract_type": "swap",
8099
+ # "trade_partition": "USDT"
8100
+ # }
8101
+ # ],
8102
+ # "ts": 1664336503144
8103
+ # }
8104
+ #
8105
+ data = self.safe_list(response, 'data', [])
8106
+ return self.parse_open_interests(data, symbols)
7650
8107
 
7651
8108
  def fetch_open_interest(self, symbol: str, params={}):
7652
8109
  """
7653
8110
  Retrieves the open interest of a currency
7654
- :see: https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information
7655
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information
7656
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information
8111
+
8112
+ https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information
8113
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information
8114
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information
8115
+
7657
8116
  :param str symbol: Unified CCXT market symbol
7658
8117
  :param dict [params]: exchange specific parameters
7659
8118
  :returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
@@ -7664,7 +8123,7 @@ class htx(Exchange, ImplicitAPI):
7664
8123
  raise BadRequest(self.id + ' fetchOpenInterest() supports contract markets only')
7665
8124
  if market['option']:
7666
8125
  raise NotSupported(self.id + ' fetchOpenInterest() does not currently support option markets')
7667
- request = {
8126
+ request: dict = {
7668
8127
  'contract_code': market['id'],
7669
8128
  }
7670
8129
  response = None
@@ -7804,8 +8263,9 @@ class htx(Exchange, ImplicitAPI):
7804
8263
  timestamp = self.safe_integer(interest, 'ts')
7805
8264
  amount = self.safe_number(interest, 'volume')
7806
8265
  value = self.safe_number(interest, 'value')
8266
+ marketId = self.safe_string(interest, 'contract_code')
7807
8267
  return self.safe_open_interest({
7808
- 'symbol': self.safe_string(market, 'symbol'),
8268
+ 'symbol': self.safe_symbol(marketId, market),
7809
8269
  'baseVolume': amount, # deprecated
7810
8270
  'quoteVolume': value, # deprecated
7811
8271
  'openInterestAmount': amount,
@@ -7818,8 +8278,10 @@ class htx(Exchange, ImplicitAPI):
7818
8278
  def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
7819
8279
  """
7820
8280
  create a loan to borrow margin
7821
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
7822
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8281
+
8282
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
8283
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8284
+
7823
8285
  :param str symbol: unified market symbol, required for isolated margin
7824
8286
  :param str code: unified currency code of the currency to borrow
7825
8287
  :param float amount: the amount to borrow
@@ -7829,7 +8291,7 @@ class htx(Exchange, ImplicitAPI):
7829
8291
  self.load_markets()
7830
8292
  currency = self.currency(code)
7831
8293
  market = self.market(symbol)
7832
- request = {
8294
+ request: dict = {
7833
8295
  'currency': currency['id'],
7834
8296
  'amount': self.currency_to_precision(code, amount),
7835
8297
  'symbol': market['id'],
@@ -7851,8 +8313,10 @@ class htx(Exchange, ImplicitAPI):
7851
8313
  def borrow_cross_margin(self, code: str, amount: float, params={}):
7852
8314
  """
7853
8315
  create a loan to borrow margin
7854
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
7855
- :see: https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8316
+
8317
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated
8318
+ https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross
8319
+
7856
8320
  :param str code: unified currency code of the currency to borrow
7857
8321
  :param float amount: the amount to borrow
7858
8322
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7860,7 +8324,7 @@ class htx(Exchange, ImplicitAPI):
7860
8324
  """
7861
8325
  self.load_markets()
7862
8326
  currency = self.currency(code)
7863
- request = {
8327
+ request: dict = {
7864
8328
  'currency': currency['id'],
7865
8329
  'amount': self.currency_to_precision(code, amount),
7866
8330
  }
@@ -7881,17 +8345,19 @@ class htx(Exchange, ImplicitAPI):
7881
8345
  def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
7882
8346
  """
7883
8347
  repay borrowed margin and interest
7884
- :see: https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8348
+
8349
+ https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8350
+
8351
+ :param str symbol: unified market symbol
7885
8352
  :param str code: unified currency code of the currency to repay
7886
8353
  :param float amount: the amount to repay
7887
- :param str symbol: unified market symbol
7888
8354
  :param dict [params]: extra parameters specific to the exchange API endpoint
7889
8355
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
7890
8356
  """
7891
8357
  self.load_markets()
7892
8358
  currency = self.currency(code)
7893
8359
  accountId = self.fetch_account_id_by_type('spot', 'isolated', symbol, params)
7894
- request = {
8360
+ request: dict = {
7895
8361
  'currency': currency['id'],
7896
8362
  'amount': self.currency_to_precision(code, amount),
7897
8363
  'accountId': accountId,
@@ -7919,7 +8385,9 @@ class htx(Exchange, ImplicitAPI):
7919
8385
  def repay_cross_margin(self, code: str, amount, params={}):
7920
8386
  """
7921
8387
  repay borrowed margin and interest
7922
- :see: https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8388
+
8389
+ https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated
8390
+
7923
8391
  :param str code: unified currency code of the currency to repay
7924
8392
  :param float amount: the amount to repay
7925
8393
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7928,7 +8396,7 @@ class htx(Exchange, ImplicitAPI):
7928
8396
  self.load_markets()
7929
8397
  currency = self.currency(code)
7930
8398
  accountId = self.fetch_account_id_by_type('spot', 'cross', None, params)
7931
- request = {
8399
+ request: dict = {
7932
8400
  'currency': currency['id'],
7933
8401
  'amount': self.currency_to_precision(code, amount),
7934
8402
  'accountId': accountId,
@@ -7988,6 +8456,11 @@ class htx(Exchange, ImplicitAPI):
7988
8456
  def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7989
8457
  """
7990
8458
  Fetches historical settlement records
8459
+
8460
+ https://huobiapi.github.io/docs/dm/v1/en/#query-historical-settlement-records-of-the-platform-interface
8461
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-settlement-records-of-the-platform-interface
8462
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-settlement-records-of-the-platform-interface
8463
+
7991
8464
  :param str symbol: unified symbol of the market to fetch the settlement history for
7992
8465
  :param int [since]: timestamp in ms, value range = current time - 90 days,default = current time - 90 days
7993
8466
  :param int [limit]: page items, default 20, shall not exceed 50
@@ -7999,10 +8472,10 @@ class htx(Exchange, ImplicitAPI):
7999
8472
  """
8000
8473
  if symbol is None:
8001
8474
  raise ArgumentsRequired(self.id + ' fetchSettlementHistory() requires a symbol argument')
8002
- until = self.safe_integer_2(params, 'until', 'till')
8003
- params = self.omit(params, ['until', 'till'])
8475
+ until = self.safe_integer(params, 'until')
8476
+ params = self.omit(params, ['until'])
8004
8477
  market = self.market(symbol)
8005
- request = {}
8478
+ request: dict = {}
8006
8479
  if market['future']:
8007
8480
  request['symbol'] = market['baseId']
8008
8481
  else:
@@ -8081,7 +8554,9 @@ class htx(Exchange, ImplicitAPI):
8081
8554
  def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
8082
8555
  """
8083
8556
  fetch deposit and withdraw fees
8084
- :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-currencies-v2
8557
+
8558
+ https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-currencies-v2
8559
+
8085
8560
  :param str[]|None codes: list of unified currency codes
8086
8561
  :param dict [params]: extra parameters specific to the exchange API endpoint
8087
8562
  :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -8124,7 +8599,7 @@ class htx(Exchange, ImplicitAPI):
8124
8599
  # ]
8125
8600
  # }
8126
8601
  #
8127
- data = self.safe_value(response, 'data')
8602
+ data = self.safe_list(response, 'data')
8128
8603
  return self.parse_deposit_withdraw_fees(data, codes, 'currency')
8129
8604
 
8130
8605
  def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
@@ -8233,7 +8708,7 @@ class htx(Exchange, ImplicitAPI):
8233
8708
  list = self.safe_value(settlement, 'list')
8234
8709
  if list is not None:
8235
8710
  timestamp = self.safe_integer(settlement, 'settlement_time')
8236
- timestampDetails = {
8711
+ timestampDetails: dict = {
8237
8712
  'timestamp': timestamp,
8238
8713
  'datetime': self.iso8601(timestamp),
8239
8714
  }
@@ -8282,9 +8757,11 @@ class htx(Exchange, ImplicitAPI):
8282
8757
  def fetch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}):
8283
8758
  """
8284
8759
  retrieves the public liquidations of a trading pair
8285
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-liquidation-orders-new
8286
- :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-liquidation-orders-new
8287
- :see: https://huobiapi.github.io/docs/dm/v1/en/#query-liquidation-order-information-new
8760
+
8761
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-liquidation-orders-new
8762
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-liquidation-orders-new
8763
+ https://huobiapi.github.io/docs/dm/v1/en/#query-liquidation-order-information-new
8764
+
8288
8765
  :param str symbol: unified CCXT market symbol
8289
8766
  :param int [since]: the earliest time in ms to fetch liquidations for
8290
8767
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -8296,7 +8773,7 @@ class htx(Exchange, ImplicitAPI):
8296
8773
  self.load_markets()
8297
8774
  market = self.market(symbol)
8298
8775
  tradeType = self.safe_integer(params, 'trade_type', 0)
8299
- request = {
8776
+ request: dict = {
8300
8777
  'trade_type': tradeType,
8301
8778
  }
8302
8779
  if since is not None:
@@ -8337,7 +8814,7 @@ class htx(Exchange, ImplicitAPI):
8337
8814
  # "ts": 1604312615051
8338
8815
  # }
8339
8816
  #
8340
- data = self.safe_value(response, 'data', [])
8817
+ data = self.safe_list(response, 'data', [])
8341
8818
  return self.parse_liquidations(data, market, since, limit)
8342
8819
 
8343
8820
  def parse_liquidation(self, liquidation, market: Market = None):
@@ -8371,11 +8848,66 @@ class htx(Exchange, ImplicitAPI):
8371
8848
  'datetime': self.iso8601(timestamp),
8372
8849
  })
8373
8850
 
8851
+ def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
8852
+ """
8853
+ closes open positions for a contract market, requires 'amount' in params, unlike other exchanges
8854
+
8855
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-lightning-close-order # USDT-M(isolated)
8856
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-lightning-close-position # USDT-M(cross)
8857
+ https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-lightning-close-order # Coin-M swap
8858
+ https://huobiapi.github.io/docs/dm/v1/en/#place-flash-close-order # Coin-M futures
8859
+
8860
+ :param str symbol: unified CCXT market symbol
8861
+ :param str side: 'buy' or 'sell', the side of the closing order, opposite side side
8862
+ :param dict [params]: extra parameters specific to the okx api endpoint
8863
+ :param str [params.clientOrderId]: client needs to provide unique API and have to maintain the API themselves afterwards. [1, 9223372036854775807]
8864
+ :param dict [params.marginMode]: 'cross' or 'isolated', required for linear markets
8865
+
8866
+ EXCHANGE SPECIFIC PARAMETERS
8867
+ :param number [params.amount]: order quantity
8868
+ :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
8869
+ :returns dict: `an order structure <https://docs.ccxt.com/#/?id=position-structure>`
8870
+ """
8871
+ self.load_markets()
8872
+ market = self.market(symbol)
8873
+ clientOrderId = self.safe_string(params, 'clientOrderId')
8874
+ if not market['contract']:
8875
+ raise BadRequest(self.id + ' closePosition() symbol supports contract markets only')
8876
+ self.check_required_argument('closePosition', side, 'side')
8877
+ request: dict = {
8878
+ 'contract_code': market['id'],
8879
+ 'direction': side,
8880
+ }
8881
+ if clientOrderId is not None:
8882
+ request['client_order_id'] = clientOrderId
8883
+ if market['inverse']:
8884
+ amount = self.safe_string_2(params, 'volume', 'amount')
8885
+ if amount is None:
8886
+ raise ArgumentsRequired(self.id + ' closePosition() requires an extra argument params["amount"] for inverse markets')
8887
+ request['volume'] = self.amount_to_precision(symbol, amount)
8888
+ params = self.omit(params, ['clientOrderId', 'volume', 'amount'])
8889
+ response = None
8890
+ if market['inverse']: # Coin-M
8891
+ if market['swap']:
8892
+ response = self.contractPrivatePostSwapApiV1SwapLightningClosePosition(self.extend(request, params))
8893
+ else: # future
8894
+ response = self.contractPrivatePostApiV1LightningClosePosition(self.extend(request, params))
8895
+ else: # USDT-M
8896
+ marginMode = None
8897
+ marginMode, params = self.handle_margin_mode_and_params('closePosition', params, 'cross')
8898
+ if marginMode == 'cross':
8899
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossLightningClosePosition(self.extend(request, params))
8900
+ else: # isolated
8901
+ response = self.contractPrivatePostLinearSwapApiV1SwapLightningClosePosition(self.extend(request, params))
8902
+ return self.parse_order(response, market)
8903
+
8374
8904
  def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
8375
8905
  """
8376
8906
  set hedged to True or False
8377
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-position-mode
8378
- :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-position-mode
8907
+
8908
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-position-mode
8909
+ https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-position-mode
8910
+
8379
8911
  :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
8380
8912
  :param str [symbol]: unified market symbol, required for isolated margin mode
8381
8913
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -8389,7 +8921,7 @@ class htx(Exchange, ImplicitAPI):
8389
8921
  market = self.market(symbol)
8390
8922
  marginMode = None
8391
8923
  marginMode, params = self.handle_margin_mode_and_params('setPositionMode', params, 'cross')
8392
- request = {
8924
+ request: dict = {
8393
8925
  'position_mode': posMode,
8394
8926
  }
8395
8927
  response = None