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/ascendex.py CHANGED
@@ -6,17 +6,18 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.ascendex import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currency, Int, Leverage, Leverages, MarginMode, MarginModes, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, Currencies, Currency, DepositAddress, Int, Leverage, Leverages, LeverageTier, LeverageTiers, MarginMode, MarginModes, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, 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
14
+ from ccxt.base.errors import AccountSuspended
13
15
  from ccxt.base.errors import ArgumentsRequired
14
16
  from ccxt.base.errors import BadRequest
15
17
  from ccxt.base.errors import BadSymbol
16
18
  from ccxt.base.errors import InsufficientFunds
17
19
  from ccxt.base.errors import InvalidOrder
18
20
  from ccxt.base.errors import NotSupported
19
- from ccxt.base.errors import AuthenticationError
20
21
  from ccxt.base.decimal_to_precision import TICK_SIZE
21
22
  from ccxt.base.precise import Precise
22
23
 
@@ -101,6 +102,7 @@ class ascendex(Exchange, ImplicitAPI):
101
102
  'fetchWithdrawal': False,
102
103
  'fetchWithdrawals': True,
103
104
  'reduceMargin': True,
105
+ 'sandbox': True,
104
106
  'setLeverage': True,
105
107
  'setMarginMode': True,
106
108
  'setPositionMode': False,
@@ -122,7 +124,7 @@ class ascendex(Exchange, ImplicitAPI):
122
124
  },
123
125
  'version': 'v2',
124
126
  'urls': {
125
- 'logo': 'https://user-images.githubusercontent.com/1294454/112027508-47984600-8b48-11eb-9e17-d26459cc36c6.jpg',
127
+ 'logo': 'https://github.com/user-attachments/assets/55bab6b9-d4ca-42a8-a0e6-fac81ae557f1',
126
128
  'api': {
127
129
  'rest': 'https://ascendex.com',
128
130
  },
@@ -291,26 +293,111 @@ class ascendex(Exchange, ImplicitAPI):
291
293
  'SOL': 'Solana',
292
294
  'AVAX': 'avalanche C chain',
293
295
  'OMNI': 'Omni',
294
- 'TRC': 'TRC20',
296
+ # 'TRC': 'TRC20',
295
297
  'TRX': 'TRC20',
296
- 'ERC': 'ERC20',
297
- },
298
- 'networksById': {
299
- 'BEP20(BSC)': 'BSC',
300
- 'arbitrum': 'ARB',
301
- 'Solana': 'SOL',
302
- 'avalanche C chain': 'AVAX',
303
- 'Omni': 'OMNI',
304
298
  'TRC20': 'TRC20',
305
299
  'ERC20': 'ERC20',
306
300
  'GO20': 'GO20',
307
301
  'BEP2': 'BEP2',
308
- 'Bitcoin': 'BTC',
309
- 'Bitcoin ABC': 'BCH',
310
- 'Litecoin': 'LTC',
311
- 'Matic Network': 'MATIC',
312
- 'xDai': 'STAKE',
313
- 'Akash': 'AKT',
302
+ 'BTC': 'Bitcoin',
303
+ 'BCH': 'Bitcoin ABC',
304
+ 'LTC': 'Litecoin',
305
+ 'MATIC': 'Matic Network',
306
+ 'AKT': 'Akash',
307
+ },
308
+ },
309
+ 'features': {
310
+ 'default': {
311
+ 'sandbox': True,
312
+ 'createOrder': {
313
+ 'marginMode': True,
314
+ 'triggerPrice': True,
315
+ 'triggerPriceType': None,
316
+ 'triggerDirection': False,
317
+ 'stopLossPrice': False, # todo with triggerprice
318
+ 'takeProfitPrice': False, # todo with triggerprice
319
+ 'attachedStopLossTakeProfit': None,
320
+ 'timeInForce': {
321
+ 'IOC': True,
322
+ 'FOK': True,
323
+ 'PO': True,
324
+ 'GTD': False,
325
+ },
326
+ 'hedged': False,
327
+ 'trailing': False,
328
+ 'leverage': False,
329
+ 'marketBuyRequiresPrice': False,
330
+ 'marketBuyByCost': False,
331
+ 'selfTradePrevention': False,
332
+ 'iceberg': False,
333
+ },
334
+ 'createOrders': {
335
+ 'max': 10,
336
+ },
337
+ 'fetchMyTrades': None,
338
+ 'fetchOrder': {
339
+ 'marginMode': False,
340
+ 'trigger': False,
341
+ 'trailing': False,
342
+ 'marketType': True,
343
+ },
344
+ 'fetchOpenOrders': {
345
+ 'marginMode': False,
346
+ 'limit': None,
347
+ 'trigger': False,
348
+ 'trailing': False,
349
+ 'marketType': True,
350
+ },
351
+ 'fetchOrders': None,
352
+ 'fetchClosedOrders': None,
353
+ 'fetchOHLCV': {
354
+ 'limit': 500,
355
+ },
356
+ },
357
+ 'spot': {
358
+ 'extends': 'default',
359
+ 'fetchClosedOrders': {
360
+ 'marginMode': False,
361
+ 'limit': 1000,
362
+ 'daysBack': 100000,
363
+ 'daysBackCanceled': 1,
364
+ 'untilDays': 100000,
365
+ 'trigger': False,
366
+ 'trailing': False,
367
+ },
368
+ },
369
+ 'forDerivatives': {
370
+ 'extends': 'default',
371
+ 'createOrder': {
372
+ # todo: implementation
373
+ 'attachedStopLossTakeProfit': {
374
+ 'triggerPriceType': {
375
+ 'last': True,
376
+ 'mark': False,
377
+ 'index': False,
378
+ },
379
+ 'price': False,
380
+ },
381
+ },
382
+ 'fetchClosedOrders': {
383
+ 'marginMode': False,
384
+ 'limit': 1000,
385
+ 'daysBack': None,
386
+ 'daysBackCanceled': None,
387
+ 'untilDays': None,
388
+ 'trigger': False,
389
+ 'trailing': False,
390
+ },
391
+ },
392
+ 'swap': {
393
+ 'linear': {
394
+ 'extends': 'forDerivatives',
395
+ },
396
+ 'inverse': None,
397
+ },
398
+ 'future': {
399
+ 'linear': None,
400
+ 'inverse': None,
314
401
  },
315
402
  },
316
403
  'exceptions': {
@@ -368,7 +455,7 @@ class ascendex(Exchange, ImplicitAPI):
368
455
  '300013': InvalidOrder, # INVALID_BATCH_ORDER Some or all orders are invalid in batch order request
369
456
  '300014': InvalidOrder, # {"code":300014,"message":"Order price doesn't conform to the required tick size: 0.1","reason":"TICK_SIZE_VIOLATION"}
370
457
  '300020': InvalidOrder, # TRADING_RESTRICTED There is some trading restriction on account or asset
371
- '300021': InvalidOrder, # TRADING_DISABLED Trading is disabled on account or asset
458
+ '300021': AccountSuspended, # {"code":300021,"message":"Trading disabled for self account.","reason":"TRADING_DISABLED"}
372
459
  '300031': InvalidOrder, # NO_MARKET_PRICE No market price for market type order trading
373
460
  '310001': InsufficientFunds, # INVALID_MARGIN_BALANCE No enough margin balance
374
461
  '310002': InvalidOrder, # INVALID_MARGIN_ACCOUNT Not a valid account for margin trading
@@ -395,13 +482,13 @@ class ascendex(Exchange, ImplicitAPI):
395
482
  lowercaseAccount = account.lower()
396
483
  return self.capitalize(lowercaseAccount)
397
484
 
398
- def fetch_currencies(self, params={}):
485
+ def fetch_currencies(self, params={}) -> Currencies:
399
486
  """
400
487
  fetches all available currencies on an exchange
401
488
  :param dict [params]: extra parameters specific to the exchange API endpoint
402
489
  :returns dict: an associative dictionary of currencies
403
490
  """
404
- assets = self.v1PublicGetAssets(params)
491
+ assetsPromise = self.v1PublicGetAssets(params)
405
492
  #
406
493
  # {
407
494
  # "code":0,
@@ -418,7 +505,7 @@ class ascendex(Exchange, ImplicitAPI):
418
505
  # ]
419
506
  # }
420
507
  #
421
- margin = self.v1PublicGetMarginAssets(params)
508
+ marginPromise = self.v1PublicGetMarginAssets(params)
422
509
  #
423
510
  # {
424
511
  # "code":0,
@@ -438,7 +525,7 @@ class ascendex(Exchange, ImplicitAPI):
438
525
  # ]
439
526
  # }
440
527
  #
441
- cash = self.v1PublicGetCashAssets(params)
528
+ cashPromise = self.v1PublicGetCashAssets(params)
442
529
  #
443
530
  # {
444
531
  # "code":0,
@@ -455,15 +542,16 @@ class ascendex(Exchange, ImplicitAPI):
455
542
  # ]
456
543
  # }
457
544
  #
458
- assetsData = self.safe_value(assets, 'data', [])
459
- marginData = self.safe_value(margin, 'data', [])
460
- cashData = self.safe_value(cash, 'data', [])
545
+ assets, margin, cash = [assetsPromise, marginPromise, cashPromise]
546
+ assetsData = self.safe_list(assets, 'data', [])
547
+ marginData = self.safe_list(margin, 'data', [])
548
+ cashData = self.safe_list(cash, 'data', [])
461
549
  assetsById = self.index_by(assetsData, 'assetCode')
462
550
  marginById = self.index_by(marginData, 'assetCode')
463
551
  cashById = self.index_by(cashData, 'assetCode')
464
552
  dataById = self.deep_extend(assetsById, marginById, cashById)
465
553
  ids = list(dataById.keys())
466
- result = {}
554
+ result: dict = {}
467
555
  for i in range(0, len(ids)):
468
556
  id = ids[i]
469
557
  currency = dataById[id]
@@ -500,13 +588,13 @@ class ascendex(Exchange, ImplicitAPI):
500
588
  }
501
589
  return result
502
590
 
503
- def fetch_markets(self, params={}):
591
+ def fetch_markets(self, params={}) -> List[Market]:
504
592
  """
505
593
  retrieves data on all markets for ascendex
506
594
  :param dict [params]: extra parameters specific to the exchange API endpoint
507
595
  :returns dict[]: an array of objects representing market data
508
596
  """
509
- products = self.v1PublicGetProducts(params)
597
+ productsPromise = self.v1PublicGetProducts(params)
510
598
  #
511
599
  # {
512
600
  # "code": 0,
@@ -527,7 +615,7 @@ class ascendex(Exchange, ImplicitAPI):
527
615
  # ]
528
616
  # }
529
617
  #
530
- cash = self.v1PublicGetCashProducts(params)
618
+ cashPromise = self.v1PublicGetCashProducts(params)
531
619
  #
532
620
  # {
533
621
  # "code": 0,
@@ -557,7 +645,7 @@ class ascendex(Exchange, ImplicitAPI):
557
645
  # ]
558
646
  # }
559
647
  #
560
- perpetuals = self.v2PublicGetFuturesContract(params)
648
+ perpetualsPromise = self.v2PublicGetFuturesContract(params)
561
649
  #
562
650
  # {
563
651
  # "code": 0,
@@ -595,10 +683,11 @@ class ascendex(Exchange, ImplicitAPI):
595
683
  # ]
596
684
  # }
597
685
  #
598
- productsData = self.safe_value(products, 'data', [])
686
+ products, cash, perpetuals = [productsPromise, cashPromise, perpetualsPromise]
687
+ productsData = self.safe_list(products, 'data', [])
599
688
  productsById = self.index_by(productsData, 'symbol')
600
- cashData = self.safe_value(cash, 'data', [])
601
- perpetualsData = self.safe_value(perpetuals, 'data', [])
689
+ cashData = self.safe_list(cash, 'data', [])
690
+ perpetualsData = self.safe_list(perpetuals, 'data', [])
602
691
  cashAndPerpetualsData = self.array_concat(cashData, perpetualsData)
603
692
  cashAndPerpetualsById = self.index_by(cashAndPerpetualsData, 'symbol')
604
693
  dataById = self.deep_extend(productsById, cashAndPerpetualsById)
@@ -607,7 +696,7 @@ class ascendex(Exchange, ImplicitAPI):
607
696
  for i in range(0, len(ids)):
608
697
  id = ids[i]
609
698
  market = dataById[id]
610
- settleId = self.safe_value(market, 'settlementAsset')
699
+ settleId = self.safe_string(market, 'settlementAsset')
611
700
  settle = self.safe_currency_code(settleId)
612
701
  status = self.safe_string(market, 'status')
613
702
  domain = self.safe_string(market, 'domain')
@@ -629,10 +718,10 @@ class ascendex(Exchange, ImplicitAPI):
629
718
  quote = self.safe_currency_code(quoteId)
630
719
  symbol = base + '/' + quote
631
720
  if swap:
632
- lotSizeFilter = self.safe_value(market, 'lotSizeFilter')
721
+ lotSizeFilter = self.safe_dict(market, 'lotSizeFilter')
633
722
  minQty = self.safe_number(lotSizeFilter, 'minQty')
634
723
  maxQty = self.safe_number(lotSizeFilter, 'maxQty')
635
- priceFilter = self.safe_value(market, 'priceFilter')
724
+ priceFilter = self.safe_dict(market, 'priceFilter')
636
725
  minPrice = self.safe_number(priceFilter, 'minPrice')
637
726
  maxPrice = self.safe_number(priceFilter, 'maxPrice')
638
727
  symbol = base + '/' + quote + ':' + settle
@@ -697,7 +786,7 @@ class ascendex(Exchange, ImplicitAPI):
697
786
  :param dict [params]: extra parameters specific to the exchange API endpoint
698
787
  :returns int: the current integer timestamp in milliseconds from the ascendex server
699
788
  """
700
- request = {
789
+ request: dict = {
701
790
  'requestTime': self.milliseconds(),
702
791
  }
703
792
  response = self.v1PublicGetExchangeInfo(self.extend(request, params))
@@ -711,7 +800,7 @@ class ascendex(Exchange, ImplicitAPI):
711
800
  # }
712
801
  # }
713
802
  #
714
- data = self.safe_value(response, 'data')
803
+ data = self.safe_dict(response, 'data', {})
715
804
  return self.safe_integer(data, 'requestReceiveAt')
716
805
 
717
806
  def fetch_accounts(self, params={}) -> List[Account]:
@@ -740,7 +829,7 @@ class ascendex(Exchange, ImplicitAPI):
740
829
  # }
741
830
  # }
742
831
  #
743
- data = self.safe_value(response, 'data', {})
832
+ data = self.safe_dict(response, 'data', {})
744
833
  accountGroup = self.safe_string(data, 'accountGroup')
745
834
  self.options['account-group'] = accountGroup
746
835
  return [
@@ -753,12 +842,12 @@ class ascendex(Exchange, ImplicitAPI):
753
842
  ]
754
843
 
755
844
  def parse_balance(self, response) -> Balances:
756
- result = {
845
+ result: dict = {
757
846
  'info': response,
758
847
  'timestamp': None,
759
848
  'datetime': None,
760
849
  }
761
- balances = self.safe_value(response, 'data', [])
850
+ balances = self.safe_list(response, 'data', [])
762
851
  for i in range(0, len(balances)):
763
852
  balance = balances[i]
764
853
  code = self.safe_currency_code(self.safe_string(balance, 'asset'))
@@ -769,12 +858,12 @@ class ascendex(Exchange, ImplicitAPI):
769
858
  return self.safe_balance(result)
770
859
 
771
860
  def parse_margin_balance(self, response):
772
- result = {
861
+ result: dict = {
773
862
  'info': response,
774
863
  'timestamp': None,
775
864
  'datetime': None,
776
865
  }
777
- balances = self.safe_value(response, 'data', [])
866
+ balances = self.safe_list(response, 'data', [])
778
867
  for i in range(0, len(balances)):
779
868
  balance = balances[i]
780
869
  code = self.safe_currency_code(self.safe_string(balance, 'asset'))
@@ -788,13 +877,13 @@ class ascendex(Exchange, ImplicitAPI):
788
877
  return self.safe_balance(result)
789
878
 
790
879
  def parse_swap_balance(self, response):
791
- result = {
880
+ result: dict = {
792
881
  'info': response,
793
882
  'timestamp': None,
794
883
  'datetime': None,
795
884
  }
796
- data = self.safe_value(response, 'data', {})
797
- collaterals = self.safe_value(data, 'collaterals', [])
885
+ data = self.safe_dict(response, 'data', {})
886
+ collaterals = self.safe_list(data, 'collaterals', [])
798
887
  for i in range(0, len(collaterals)):
799
888
  balance = collaterals[i]
800
889
  code = self.safe_currency_code(self.safe_string(balance, 'asset'))
@@ -806,9 +895,11 @@ class ascendex(Exchange, ImplicitAPI):
806
895
  def fetch_balance(self, params={}) -> Balances:
807
896
  """
808
897
  query for balance and get the amount of funds available for trading or funds locked in orders
809
- :see: https://ascendex.github.io/ascendex-pro-api/#cash-account-balance
810
- :see: https://ascendex.github.io/ascendex-pro-api/#margin-account-balance
811
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
898
+
899
+ https://ascendex.github.io/ascendex-pro-api/#cash-account-balance
900
+ https://ascendex.github.io/ascendex-pro-api/#margin-account-balance
901
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
902
+
812
903
  :param dict [params]: extra parameters specific to the exchange API endpoint
813
904
  :param str [params.type]: wallet type, 'spot', 'margin', or 'swap'
814
905
  :param str [params.marginMode]: 'cross' or None, for spot margin trading, value of 'isolated' is invalid
@@ -824,11 +915,11 @@ class ascendex(Exchange, ImplicitAPI):
824
915
  isCross = marginMode == 'cross'
825
916
  marketType = 'margin' if (isMargin or isCross) else marketType
826
917
  params = self.omit(params, 'margin')
827
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
918
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
828
919
  accountCategory = self.safe_string(accountsByType, marketType, 'cash')
829
- account = self.safe_value(self.accounts, 0, {})
920
+ account = self.safe_dict(self.accounts, 0, {})
830
921
  accountGroup = self.safe_string(account, 'id')
831
- request = {
922
+ request: dict = {
832
923
  'account-group': accountGroup,
833
924
  }
834
925
  if (marginMode == 'isolated') and (marketType != 'swap'):
@@ -902,7 +993,7 @@ class ascendex(Exchange, ImplicitAPI):
902
993
  """
903
994
  self.load_markets()
904
995
  market = self.market(symbol)
905
- request = {
996
+ request: dict = {
906
997
  'symbol': market['id'],
907
998
  }
908
999
  response = self.v1PublicGetDepth(self.extend(request, params))
@@ -929,14 +1020,14 @@ class ascendex(Exchange, ImplicitAPI):
929
1020
  # }
930
1021
  # }
931
1022
  #
932
- data = self.safe_value(response, 'data', {})
933
- orderbook = self.safe_value(data, 'data', {})
1023
+ data = self.safe_dict(response, 'data', {})
1024
+ orderbook = self.safe_dict(data, 'data', {})
934
1025
  timestamp = self.safe_integer(orderbook, 'ts')
935
1026
  result = self.parse_order_book(orderbook, symbol, timestamp)
936
1027
  result['nonce'] = self.safe_integer(orderbook, 'seqnum')
937
1028
  return result
938
1029
 
939
- def parse_ticker(self, ticker, market: Market = None) -> Ticker:
1030
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
940
1031
  #
941
1032
  # {
942
1033
  # "symbol":"QTUM/BTC",
@@ -956,8 +1047,8 @@ class ascendex(Exchange, ImplicitAPI):
956
1047
  delimiter = '/' if (type == 'spot') else None
957
1048
  symbol = self.safe_symbol(marketId, market, delimiter)
958
1049
  close = self.safe_string(ticker, 'close')
959
- bid = self.safe_value(ticker, 'bid', [])
960
- ask = self.safe_value(ticker, 'ask', [])
1050
+ bid = self.safe_list(ticker, 'bid', [])
1051
+ ask = self.safe_list(ticker, 'ask', [])
961
1052
  open = self.safe_string(ticker, 'open')
962
1053
  return self.safe_ticker({
963
1054
  'symbol': symbol,
@@ -991,7 +1082,7 @@ class ascendex(Exchange, ImplicitAPI):
991
1082
  """
992
1083
  self.load_markets()
993
1084
  market = self.market(symbol)
994
- request = {
1085
+ request: dict = {
995
1086
  'symbol': market['id'],
996
1087
  }
997
1088
  response = self.v1PublicGetTicker(self.extend(request, params))
@@ -1011,23 +1102,25 @@ class ascendex(Exchange, ImplicitAPI):
1011
1102
  # }
1012
1103
  # }
1013
1104
  #
1014
- data = self.safe_value(response, 'data', {})
1105
+ data = self.safe_dict(response, 'data', {})
1015
1106
  return self.parse_ticker(data, market)
1016
1107
 
1017
1108
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1018
1109
  """
1019
1110
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1020
- :see: https://ascendex.github.io/ascendex-pro-api/#ticker
1021
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#ticker
1111
+
1112
+ https://ascendex.github.io/ascendex-pro-api/#ticker
1113
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#ticker
1114
+
1022
1115
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1023
1116
  :param dict [params]: extra parameters specific to the exchange API endpoint
1024
1117
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1025
1118
  """
1026
1119
  self.load_markets()
1027
- request = {}
1120
+ request: dict = {}
1028
1121
  market = None
1029
1122
  if symbols is not None:
1030
- symbol = self.safe_value(symbols, 0)
1123
+ symbol = self.safe_string(symbols, 0)
1031
1124
  market = self.market(symbol)
1032
1125
  marketIds = self.market_ids(symbols)
1033
1126
  request['symbol'] = ','.join(marketIds)
@@ -1041,22 +1134,20 @@ class ascendex(Exchange, ImplicitAPI):
1041
1134
  #
1042
1135
  # {
1043
1136
  # "code":0,
1044
- # "data":[
1045
- # {
1046
- # "symbol":"QTUM/BTC",
1047
- # "open":"0.00016537",
1048
- # "close":"0.00019077",
1049
- # "high":"0.000192",
1050
- # "low":"0.00016537",
1051
- # "volume":"846.6",
1052
- # "ask":["0.00018698","26.2"],
1053
- # "bid":["0.00018408","503.7"],
1054
- # "type":"spot"
1055
- # }
1056
- # ]
1137
+ # "data": {
1138
+ # "symbol":"QTUM/BTC",
1139
+ # "open":"0.00016537",
1140
+ # "close":"0.00019077",
1141
+ # "high":"0.000192",
1142
+ # "low":"0.00016537",
1143
+ # "volume":"846.6",
1144
+ # "ask":["0.00018698","26.2"],
1145
+ # "bid":["0.00018408","503.7"],
1146
+ # "type":"spot"
1147
+ # }
1057
1148
  # }
1058
1149
  #
1059
- data = self.safe_value(response, 'data', [])
1150
+ data = self.safe_list(response, 'data', [])
1060
1151
  if not isinstance(data, list):
1061
1152
  return self.parse_tickers([data], symbols)
1062
1153
  return self.parse_tickers(data, symbols)
@@ -1077,7 +1168,7 @@ class ascendex(Exchange, ImplicitAPI):
1077
1168
  # }
1078
1169
  # }
1079
1170
  #
1080
- data = self.safe_value(ohlcv, 'data', {})
1171
+ data = self.safe_dict(ohlcv, 'data', {})
1081
1172
  return [
1082
1173
  self.safe_integer(data, 'ts'),
1083
1174
  self.safe_number(data, 'o'),
@@ -1095,28 +1186,42 @@ class ascendex(Exchange, ImplicitAPI):
1095
1186
  :param int [since]: timestamp in ms of the earliest candle to fetch
1096
1187
  :param int [limit]: the maximum amount of candles to fetch
1097
1188
  :param dict [params]: extra parameters specific to the exchange API endpoint
1189
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
1098
1190
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
1099
1191
  """
1100
1192
  self.load_markets()
1101
1193
  market = self.market(symbol)
1102
- request = {
1194
+ request: dict = {
1103
1195
  'symbol': market['id'],
1104
1196
  'interval': self.safe_string(self.timeframes, timeframe, timeframe),
1105
1197
  }
1106
1198
  # if since and limit are not specified
1107
1199
  # the exchange will return just 1 last candle by default
1108
1200
  duration = self.parse_timeframe(timeframe)
1109
- options = self.safe_value(self.options, 'fetchOHLCV', {})
1201
+ options = self.safe_dict(self.options, 'fetchOHLCV', {})
1110
1202
  defaultLimit = self.safe_integer(options, 'limit', 500)
1203
+ until = self.safe_integer(params, 'until')
1111
1204
  if since is not None:
1112
1205
  request['from'] = since
1113
1206
  if limit is None:
1114
1207
  limit = defaultLimit
1115
1208
  else:
1116
1209
  limit = min(limit, defaultLimit)
1117
- request['to'] = self.sum(since, limit * duration * 1000, 1)
1210
+ toWithLimit = self.sum(since, limit * duration * 1000, 1)
1211
+ if until is not None:
1212
+ request['to'] = min(toWithLimit, until + 1)
1213
+ else:
1214
+ request['to'] = toWithLimit
1215
+ elif until is not None:
1216
+ request['to'] = until + 1
1217
+ if limit is None:
1218
+ limit = defaultLimit
1219
+ else:
1220
+ limit = min(limit, defaultLimit)
1221
+ request['from'] = until - (limit * duration * 1000)
1118
1222
  elif limit is not None:
1119
1223
  request['n'] = limit # max 500
1224
+ params = self.omit(params, 'until')
1120
1225
  response = self.v1PublicGetBarhist(self.extend(request, params))
1121
1226
  #
1122
1227
  # {
@@ -1138,10 +1243,10 @@ class ascendex(Exchange, ImplicitAPI):
1138
1243
  # ]
1139
1244
  # }
1140
1245
  #
1141
- data = self.safe_value(response, 'data', [])
1246
+ data = self.safe_list(response, 'data', [])
1142
1247
  return self.parse_ohlcvs(data, market, timeframe, since, limit)
1143
1248
 
1144
- def parse_trade(self, trade, market: Market = None) -> Trade:
1249
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
1145
1250
  #
1146
1251
  # public fetchTrades
1147
1252
  #
@@ -1178,7 +1283,9 @@ class ascendex(Exchange, ImplicitAPI):
1178
1283
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1179
1284
  """
1180
1285
  get the list of most recent trades for a particular symbol
1181
- :see: https://ascendex.github.io/ascendex-pro-api/#market-trades
1286
+
1287
+ https://ascendex.github.io/ascendex-pro-api/#market-trades
1288
+
1182
1289
  :param str symbol: unified symbol of the market to fetch trades for
1183
1290
  :param int [since]: timestamp in ms of the earliest trade to fetch
1184
1291
  :param int [limit]: the maximum amount of trades to fetch
@@ -1187,7 +1294,7 @@ class ascendex(Exchange, ImplicitAPI):
1187
1294
  """
1188
1295
  self.load_markets()
1189
1296
  market = self.market(symbol)
1190
- request = {
1297
+ request: dict = {
1191
1298
  'symbol': market['id'],
1192
1299
  }
1193
1300
  if limit is not None:
@@ -1207,12 +1314,12 @@ class ascendex(Exchange, ImplicitAPI):
1207
1314
  # }
1208
1315
  # }
1209
1316
  #
1210
- records = self.safe_value(response, 'data', [])
1211
- trades = self.safe_value(records, 'data', [])
1317
+ records = self.safe_dict(response, 'data', {})
1318
+ trades = self.safe_list(records, 'data', [])
1212
1319
  return self.parse_trades(trades, market, since, limit)
1213
1320
 
1214
- def parse_order_status(self, status):
1215
- statuses = {
1321
+ def parse_order_status(self, status: Str):
1322
+ statuses: dict = {
1216
1323
  'PendingNew': 'open',
1217
1324
  'New': 'open',
1218
1325
  'PartiallyFilled': 'open',
@@ -1222,7 +1329,7 @@ class ascendex(Exchange, ImplicitAPI):
1222
1329
  }
1223
1330
  return self.safe_string(statuses, status, status)
1224
1331
 
1225
- def parse_order(self, order, market: Market = None) -> Order:
1332
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1226
1333
  #
1227
1334
  # createOrder
1228
1335
  #
@@ -1360,7 +1467,7 @@ class ascendex(Exchange, ImplicitAPI):
1360
1467
  'cost': feeCost,
1361
1468
  'currency': feeCurrencyCode,
1362
1469
  }
1363
- stopPrice = self.safe_number(order, 'stopPrice')
1470
+ triggerPrice = self.omit_zero(self.safe_string(order, 'stopPrice'))
1364
1471
  reduceOnly = None
1365
1472
  execInst = self.safe_string(order, 'execInst')
1366
1473
  if execInst == 'reduceOnly':
@@ -1382,8 +1489,7 @@ class ascendex(Exchange, ImplicitAPI):
1382
1489
  'reduceOnly': reduceOnly,
1383
1490
  'side': side,
1384
1491
  'price': price,
1385
- 'stopPrice': stopPrice,
1386
- 'triggerPrice': stopPrice,
1492
+ 'triggerPrice': triggerPrice,
1387
1493
  'amount': amount,
1388
1494
  'cost': None,
1389
1495
  'average': average,
@@ -1394,7 +1500,7 @@ class ascendex(Exchange, ImplicitAPI):
1394
1500
  'trades': None,
1395
1501
  }, market)
1396
1502
 
1397
- def fetch_trading_fees(self, params={}):
1503
+ def fetch_trading_fees(self, params={}) -> TradingFees:
1398
1504
  """
1399
1505
  fetch the trading fees for multiple markets
1400
1506
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1402,9 +1508,9 @@ class ascendex(Exchange, ImplicitAPI):
1402
1508
  """
1403
1509
  self.load_markets()
1404
1510
  self.load_accounts()
1405
- account = self.safe_value(self.accounts, 0, {})
1511
+ account = self.safe_dict(self.accounts, 0, {})
1406
1512
  accountGroup = self.safe_string(account, 'id')
1407
- request = {
1513
+ request: dict = {
1408
1514
  'account-group': accountGroup,
1409
1515
  }
1410
1516
  response = self.v1PrivateAccountGroupGetSpotFee(self.extend(request, params))
@@ -1424,35 +1530,37 @@ class ascendex(Exchange, ImplicitAPI):
1424
1530
  # }
1425
1531
  # }
1426
1532
  #
1427
- data = self.safe_value(response, 'data', {})
1428
- fees = self.safe_value(data, 'fees', [])
1429
- result = {}
1533
+ data = self.safe_dict(response, 'data', {})
1534
+ fees = self.safe_list(data, 'fees', [])
1535
+ result: dict = {}
1430
1536
  for i in range(0, len(fees)):
1431
1537
  fee = fees[i]
1432
1538
  marketId = self.safe_string(fee, 'symbol')
1433
1539
  symbol = self.safe_symbol(marketId, None, '/')
1434
- takerMaker = self.safe_value(fee, 'fee', {})
1540
+ takerMaker = self.safe_dict(fee, 'fee', {})
1435
1541
  result[symbol] = {
1436
1542
  'info': fee,
1437
1543
  'symbol': symbol,
1438
1544
  'maker': self.safe_number(takerMaker, 'maker'),
1439
1545
  'taker': self.safe_number(takerMaker, 'taker'),
1546
+ 'percentage': None,
1547
+ 'tierBased': None,
1440
1548
  }
1441
1549
  return result
1442
1550
 
1443
1551
  def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1444
1552
  """
1445
- * @ignore
1553
+ @ignore
1446
1554
  helper function to build request
1447
1555
  :param str symbol: unified symbol of the market to create an order in
1448
1556
  :param str type: 'market' or 'limit'
1449
1557
  :param str side: 'buy' or 'sell'
1450
1558
  :param float amount: how much you want to trade in units of the base currency
1451
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1559
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1452
1560
  :param dict [params]: extra parameters specific to the exchange API endpoint
1453
1561
  :param str [params.timeInForce]: "GTC", "IOC", "FOK", or "PO"
1454
1562
  :param bool [params.postOnly]: True or False
1455
- :param float [params.stopPrice]: the price at which a trigger order is triggered at
1563
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1456
1564
  :returns dict: request to be sent to the exchange
1457
1565
  """
1458
1566
  market = self.market(symbol)
@@ -1460,14 +1568,14 @@ class ascendex(Exchange, ImplicitAPI):
1460
1568
  marketType = None
1461
1569
  marginMode, params = self.handle_margin_mode_and_params('createOrderRequest', params)
1462
1570
  marketType, params = self.handle_market_type_and_params('createOrderRequest', market, params)
1463
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
1571
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
1464
1572
  accountCategory = self.safe_string(accountsByType, marketType, 'cash')
1465
1573
  if marginMode is not None:
1466
1574
  accountCategory = 'margin'
1467
- account = self.safe_value(self.accounts, 0, {})
1468
- accountGroup = self.safe_value(account, 'id')
1575
+ account = self.safe_dict(self.accounts, 0, {})
1576
+ accountGroup = self.safe_string(account, 'id')
1469
1577
  clientOrderId = self.safe_string_2(params, 'clientOrderId', 'id')
1470
- request = {
1578
+ request: dict = {
1471
1579
  'account-group': accountGroup,
1472
1580
  'account-category': accountCategory,
1473
1581
  'symbol': market['id'],
@@ -1483,7 +1591,7 @@ class ascendex(Exchange, ImplicitAPI):
1483
1591
  timeInForce = self.safe_string(params, 'timeInForce')
1484
1592
  postOnly = self.is_post_only(isMarketOrder, False, params)
1485
1593
  reduceOnly = self.safe_bool(params, 'reduceOnly', False)
1486
- stopPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
1594
+ triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1487
1595
  if isLimitOrder:
1488
1596
  request['orderPrice'] = self.price_to_precision(symbol, price)
1489
1597
  if timeInForce == 'IOC':
@@ -1492,8 +1600,8 @@ class ascendex(Exchange, ImplicitAPI):
1492
1600
  request['timeInForce'] = 'FOK'
1493
1601
  if postOnly:
1494
1602
  request['postOnly'] = True
1495
- if stopPrice is not None:
1496
- request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
1603
+ if triggerPrice is not None:
1604
+ request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
1497
1605
  if isLimitOrder:
1498
1606
  request['orderType'] = 'stop_limit'
1499
1607
  elif isMarketOrder:
@@ -1515,17 +1623,19 @@ class ascendex(Exchange, ImplicitAPI):
1515
1623
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1516
1624
  """
1517
1625
  create a trade order on the exchange
1518
- :see: https://ascendex.github.io/ascendex-pro-api/#place-order
1519
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#new-order
1626
+
1627
+ https://ascendex.github.io/ascendex-pro-api/#place-order
1628
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#new-order
1629
+
1520
1630
  :param str symbol: unified CCXT market symbol
1521
1631
  :param str type: "limit" or "market"
1522
1632
  :param str side: "buy" or "sell"
1523
1633
  :param float amount: the amount of currency to trade
1524
- :param float [price]: *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
1634
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1525
1635
  :param dict [params]: extra parameters specific to the exchange API endpoint
1526
1636
  :param str [params.timeInForce]: "GTC", "IOC", "FOK", or "PO"
1527
1637
  :param bool [params.postOnly]: True or False
1528
- :param float [params.stopPrice]: the price at which a trigger order is triggered at
1638
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1529
1639
  :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered(perpetual swap markets only)
1530
1640
  :param float [params.takeProfit.triggerPrice]: *swap only* take profit trigger price
1531
1641
  :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered(perpetual swap markets only)
@@ -1604,20 +1714,22 @@ class ascendex(Exchange, ImplicitAPI):
1604
1714
  # }
1605
1715
  # }
1606
1716
  #
1607
- data = self.safe_value(response, 'data', {})
1608
- order = self.safe_value_2(data, 'order', 'info', {})
1717
+ data = self.safe_dict(response, 'data', {})
1718
+ order = self.safe_dict_2(data, 'order', 'info', {})
1609
1719
  return self.parse_order(order, market)
1610
1720
 
1611
1721
  def create_orders(self, orders: List[OrderRequest], params={}):
1612
1722
  """
1613
1723
  create a list of trade orders
1614
- :see: https://ascendex.github.io/ascendex-pro-api/#place-batch-orders
1615
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#place-batch-orders
1724
+
1725
+ https://ascendex.github.io/ascendex-pro-api/#place-batch-orders
1726
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#place-batch-orders
1727
+
1616
1728
  :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
1617
1729
  :param dict [params]: extra parameters specific to the exchange API endpoint
1618
1730
  :param str [params.timeInForce]: "GTC", "IOC", "FOK", or "PO"
1619
1731
  :param bool [params.postOnly]: True or False
1620
- :param float [params.stopPrice]: the price at which a trigger order is triggered at
1732
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1621
1733
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1622
1734
  """
1623
1735
  self.load_markets()
@@ -1635,9 +1747,9 @@ class ascendex(Exchange, ImplicitAPI):
1635
1747
  raise BadRequest(self.id + ' createOrders() requires all orders to have the same symbol')
1636
1748
  type = self.safe_string(rawOrder, 'type')
1637
1749
  side = self.safe_string(rawOrder, 'side')
1638
- amount = self.safe_value(rawOrder, 'amount')
1639
- price = self.safe_value(rawOrder, 'price')
1640
- orderParams = self.safe_value(rawOrder, 'params', {})
1750
+ amount = self.safe_number(rawOrder, 'amount')
1751
+ price = self.safe_number(rawOrder, 'price')
1752
+ orderParams = self.safe_dict(rawOrder, 'params', {})
1641
1753
  marginResult = self.handle_margin_mode_and_params('createOrders', orderParams)
1642
1754
  currentMarginMode = marginResult[0]
1643
1755
  if currentMarginMode is not None:
@@ -1649,13 +1761,13 @@ class ascendex(Exchange, ImplicitAPI):
1649
1761
  orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
1650
1762
  ordersRequests.append(orderRequest)
1651
1763
  market = self.market(symbol)
1652
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
1764
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
1653
1765
  accountCategory = self.safe_string(accountsByType, market['type'], 'cash')
1654
1766
  if marginMode is not None:
1655
1767
  accountCategory = 'margin'
1656
- account = self.safe_value(self.accounts, 0, {})
1657
- accountGroup = self.safe_value(account, 'id')
1658
- request = {}
1768
+ account = self.safe_dict(self.accounts, 0, {})
1769
+ accountGroup = self.safe_string(account, 'id')
1770
+ request: dict = {}
1659
1771
  response = None
1660
1772
  if market['swap']:
1661
1773
  raise NotSupported(self.id + ' createOrders() is not currently supported for swap markets on ascendex')
@@ -1690,15 +1802,18 @@ class ascendex(Exchange, ImplicitAPI):
1690
1802
  # }
1691
1803
  # }
1692
1804
  #
1693
- data = self.safe_value(response, 'data', {})
1694
- info = self.safe_value(data, 'info', [])
1805
+ data = self.safe_dict(response, 'data', {})
1806
+ info = self.safe_list(data, 'info', [])
1695
1807
  return self.parse_orders(info, market)
1696
1808
 
1697
1809
  def fetch_order(self, id: str, symbol: Str = None, params={}):
1698
1810
  """
1699
1811
  fetches information on an order made by the user
1700
- :see: https://ascendex.github.io/ascendex-pro-api/#query-order
1701
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#query-order-by-id
1812
+
1813
+ https://ascendex.github.io/ascendex-pro-api/#query-order
1814
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#query-order-by-id
1815
+
1816
+ :param str id: the order id
1702
1817
  :param str symbol: unified symbol of the market the order was made in
1703
1818
  :param dict [params]: extra parameters specific to the exchange API endpoint
1704
1819
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -1709,11 +1824,11 @@ class ascendex(Exchange, ImplicitAPI):
1709
1824
  if symbol is not None:
1710
1825
  market = self.market(symbol)
1711
1826
  type, query = self.handle_market_type_and_params('fetchOrder', market, params)
1712
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
1827
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
1713
1828
  accountCategory = self.safe_string(accountsByType, type, 'cash')
1714
- account = self.safe_value(self.accounts, 0, {})
1715
- accountGroup = self.safe_value(account, 'id')
1716
- request = {
1829
+ account = self.safe_dict(self.accounts, 0, {})
1830
+ accountGroup = self.safe_string(account, 'id')
1831
+ request: dict = {
1717
1832
  'account-group': accountGroup,
1718
1833
  'account-category': accountCategory,
1719
1834
  'orderId': id,
@@ -1793,14 +1908,16 @@ class ascendex(Exchange, ImplicitAPI):
1793
1908
  # }
1794
1909
  # }
1795
1910
  #
1796
- data = self.safe_value(response, 'data', {})
1911
+ data = self.safe_dict(response, 'data', {})
1797
1912
  return self.parse_order(data, market)
1798
1913
 
1799
1914
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1800
1915
  """
1801
1916
  fetch all unfilled currently open orders
1802
- :see: https://ascendex.github.io/ascendex-pro-api/#list-open-orders
1803
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#list-open-orders
1917
+
1918
+ https://ascendex.github.io/ascendex-pro-api/#list-open-orders
1919
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#list-open-orders
1920
+
1804
1921
  :param str symbol: unified market symbol
1805
1922
  :param int [since]: the earliest time in ms to fetch open orders for
1806
1923
  :param int [limit]: the maximum number of open orders structures to retrieve
@@ -1813,12 +1930,12 @@ class ascendex(Exchange, ImplicitAPI):
1813
1930
  if symbol is not None:
1814
1931
  market = self.market(symbol)
1815
1932
  symbol = market['symbol']
1816
- account = self.safe_value(self.accounts, 0, {})
1817
- accountGroup = self.safe_value(account, 'id')
1933
+ account = self.safe_dict(self.accounts, 0, {})
1934
+ accountGroup = self.safe_string(account, 'id')
1818
1935
  type, query = self.handle_market_type_and_params('fetchOpenOrders', market, params)
1819
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
1936
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
1820
1937
  accountCategory = self.safe_string(accountsByType, type, 'cash')
1821
- request = {
1938
+ request: dict = {
1822
1939
  'account-group': accountGroup,
1823
1940
  'account-category': accountCategory,
1824
1941
  }
@@ -1897,7 +2014,7 @@ class ascendex(Exchange, ImplicitAPI):
1897
2014
  # ]
1898
2015
  # }
1899
2016
  #
1900
- data = self.safe_value(response, 'data', [])
2017
+ data = self.safe_list(response, 'data', [])
1901
2018
  if accountCategory == 'futures':
1902
2019
  return self.parse_orders(data, market, since, limit)
1903
2020
  # a workaround for https://github.com/ccxt/ccxt/issues/7187
@@ -1910,8 +2027,10 @@ class ascendex(Exchange, ImplicitAPI):
1910
2027
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1911
2028
  """
1912
2029
  fetches information on multiple closed orders made by the user
1913
- :see: https://ascendex.github.io/ascendex-pro-api/#list-history-orders-v2
1914
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#list-current-history-orders
2030
+
2031
+ https://ascendex.github.io/ascendex-pro-api/#list-history-orders-v2
2032
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#list-current-history-orders
2033
+
1915
2034
  :param str symbol: unified market symbol of the market orders were made in
1916
2035
  :param int [since]: the earliest time in ms to fetch orders for
1917
2036
  :param int [limit]: the maximum number of order structures to retrieve
@@ -1921,9 +2040,9 @@ class ascendex(Exchange, ImplicitAPI):
1921
2040
  """
1922
2041
  self.load_markets()
1923
2042
  self.load_accounts()
1924
- account = self.safe_value(self.accounts, 0, {})
1925
- accountGroup = self.safe_value(account, 'id')
1926
- request = {
2043
+ account = self.safe_dict(self.accounts, 0, {})
2044
+ accountGroup = self.safe_string(account, 'id')
2045
+ request: dict = {
1927
2046
  # 'category': accountCategory,
1928
2047
  # 'symbol': market['id'],
1929
2048
  # 'orderType': 'market', # optional, string
@@ -1939,7 +2058,7 @@ class ascendex(Exchange, ImplicitAPI):
1939
2058
  market = self.market(symbol)
1940
2059
  request['symbol'] = market['id']
1941
2060
  type, query = self.handle_market_type_and_params('fetchClosedOrders', market, params)
1942
- options = self.safe_value(self.options, 'fetchClosedOrders', {})
2061
+ options = self.safe_dict(self.options, 'fetchClosedOrders', {})
1943
2062
  defaultMethod = self.safe_string(options, 'method', 'v2PrivateDataGetOrderHist')
1944
2063
  method = self.get_supported_mapping(type, {
1945
2064
  'spot': defaultMethod,
@@ -1951,7 +2070,7 @@ class ascendex(Exchange, ImplicitAPI):
1951
2070
  until = self.safe_string(params, 'until')
1952
2071
  if until is not None:
1953
2072
  request['endTime'] = until
1954
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
2073
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
1955
2074
  accountCategory = self.safe_string(accountsByType, type, 'cash') # margin, futures
1956
2075
  response = None
1957
2076
  if method == 'v1PrivateAccountCategoryGetOrderHistCurrent':
@@ -2064,17 +2183,19 @@ class ascendex(Exchange, ImplicitAPI):
2064
2183
  # ]
2065
2184
  # }
2066
2185
  #
2067
- data = self.safe_value(response, 'data')
2186
+ data = self.safe_list(response, 'data', [])
2068
2187
  isArray = isinstance(data, list)
2069
2188
  if not isArray:
2070
- data = self.safe_value(data, 'data', [])
2189
+ data = self.safe_list(data, 'data', [])
2071
2190
  return self.parse_orders(data, market, since, limit)
2072
2191
 
2073
2192
  def cancel_order(self, id: str, symbol: Str = None, params={}):
2074
2193
  """
2075
2194
  cancels an open order
2076
- :see: https://ascendex.github.io/ascendex-pro-api/#cancel-order
2077
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#cancel-order
2195
+
2196
+ https://ascendex.github.io/ascendex-pro-api/#cancel-order
2197
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#cancel-order
2198
+
2078
2199
  :param str id: order id
2079
2200
  :param str symbol: unified symbol of the market the order was made in
2080
2201
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2086,11 +2207,11 @@ class ascendex(Exchange, ImplicitAPI):
2086
2207
  self.load_accounts()
2087
2208
  market = self.market(symbol)
2088
2209
  type, query = self.handle_market_type_and_params('cancelOrder', market, params)
2089
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
2210
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
2090
2211
  accountCategory = self.safe_string(accountsByType, type, 'cash')
2091
- account = self.safe_value(self.accounts, 0, {})
2092
- accountGroup = self.safe_value(account, 'id')
2093
- request = {
2212
+ account = self.safe_dict(self.accounts, 0, {})
2213
+ accountGroup = self.safe_string(account, 'id')
2214
+ request: dict = {
2094
2215
  'account-group': accountGroup,
2095
2216
  'account-category': accountCategory,
2096
2217
  'symbol': market['id'],
@@ -2174,18 +2295,20 @@ class ascendex(Exchange, ImplicitAPI):
2174
2295
  # }
2175
2296
  # }
2176
2297
  #
2177
- data = self.safe_value(response, 'data', {})
2178
- order = self.safe_value_2(data, 'order', 'info', {})
2298
+ data = self.safe_dict(response, 'data', {})
2299
+ order = self.safe_dict_2(data, 'order', 'info', {})
2179
2300
  return self.parse_order(order, market)
2180
2301
 
2181
2302
  def cancel_all_orders(self, symbol: Str = None, params={}):
2182
2303
  """
2183
2304
  cancel all open orders
2184
- :see: https://ascendex.github.io/ascendex-pro-api/#cancel-all-orders
2185
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#cancel-all-open-orders
2305
+
2306
+ https://ascendex.github.io/ascendex-pro-api/#cancel-all-orders
2307
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#cancel-all-open-orders
2308
+
2186
2309
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
2187
2310
  :param dict [params]: extra parameters specific to the exchange API endpoint
2188
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
2311
+ :returns dict[]: a list with a single `order structure <https://docs.ccxt.com/#/?id=order-structure>` with the response assigned to the info property
2189
2312
  """
2190
2313
  self.load_markets()
2191
2314
  self.load_accounts()
@@ -2193,11 +2316,11 @@ class ascendex(Exchange, ImplicitAPI):
2193
2316
  if symbol is not None:
2194
2317
  market = self.market(symbol)
2195
2318
  type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
2196
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
2319
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
2197
2320
  accountCategory = self.safe_string(accountsByType, type, 'cash')
2198
- account = self.safe_value(self.accounts, 0, {})
2199
- accountGroup = self.safe_value(account, 'id')
2200
- request = {
2321
+ account = self.safe_dict(self.accounts, 0, {})
2322
+ accountGroup = self.safe_string(account, 'id')
2323
+ request: dict = {
2201
2324
  'account-group': accountGroup,
2202
2325
  'account-category': accountCategory,
2203
2326
  'time': self.milliseconds(),
@@ -2246,9 +2369,11 @@ class ascendex(Exchange, ImplicitAPI):
2246
2369
  # }
2247
2370
  # }
2248
2371
  #
2249
- return response
2372
+ return self.safe_order({
2373
+ 'info': response,
2374
+ })
2250
2375
 
2251
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
2376
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
2252
2377
  #
2253
2378
  # {
2254
2379
  # "address": "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
@@ -2270,21 +2395,19 @@ class ascendex(Exchange, ImplicitAPI):
2270
2395
  chainName = self.safe_string(depositAddress, 'blockchain')
2271
2396
  network = self.network_id_to_code(chainName, code)
2272
2397
  return {
2398
+ 'info': depositAddress,
2273
2399
  'currency': code,
2400
+ 'network': network,
2274
2401
  'address': address,
2275
2402
  'tag': tag,
2276
- 'network': network,
2277
- 'info': depositAddress,
2278
2403
  }
2279
2404
 
2280
- def safe_network(self, networkId):
2281
- networksById = self.safe_dict(self.options, 'networksById')
2282
- return self.safe_string(networksById, networkId, networkId)
2283
-
2284
- def fetch_deposit_address(self, code: str, params={}):
2405
+ def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
2285
2406
  """
2286
2407
  fetch the deposit address for a currency associated with self account
2287
- :see: https://ascendex.github.io/ascendex-pro-api/#query-deposit-addresses
2408
+
2409
+ https://ascendex.github.io/ascendex-pro-api/#query-deposit-addresses
2410
+
2288
2411
  :param str code: unified currency code
2289
2412
  :param dict [params]: extra parameters specific to the exchange API endpoint
2290
2413
  :param str [params.network]: unified network code for deposit chain
@@ -2295,7 +2418,7 @@ class ascendex(Exchange, ImplicitAPI):
2295
2418
  networkCode = self.safe_string_2(params, 'network', 'chainName')
2296
2419
  networkId = self.network_code_to_id(networkCode)
2297
2420
  params = self.omit(params, ['chainName'])
2298
- request = {
2421
+ request: dict = {
2299
2422
  'asset': currency['id'],
2300
2423
  'blockchain': networkId,
2301
2424
  }
@@ -2361,7 +2484,7 @@ class ascendex(Exchange, ImplicitAPI):
2361
2484
  :param dict [params]: extra parameters specific to the exchange API endpoint
2362
2485
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2363
2486
  """
2364
- request = {
2487
+ request: dict = {
2365
2488
  'txType': 'deposit',
2366
2489
  }
2367
2490
  return self.fetch_transactions(code, since, limit, self.extend(request, params))
@@ -2375,7 +2498,7 @@ class ascendex(Exchange, ImplicitAPI):
2375
2498
  :param dict [params]: extra parameters specific to the exchange API endpoint
2376
2499
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2377
2500
  """
2378
- request = {
2501
+ request: dict = {
2379
2502
  'txType': 'withdrawal',
2380
2503
  }
2381
2504
  return self.fetch_transactions(code, since, limit, self.extend(request, params))
@@ -2390,7 +2513,7 @@ class ascendex(Exchange, ImplicitAPI):
2390
2513
  :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2391
2514
  """
2392
2515
  self.load_markets()
2393
- request = {
2516
+ request: dict = {
2394
2517
  # 'asset': currency['id'],
2395
2518
  # 'page': 1,
2396
2519
  # 'pageSize': 20,
@@ -2432,12 +2555,12 @@ class ascendex(Exchange, ImplicitAPI):
2432
2555
  # }
2433
2556
  # }
2434
2557
  #
2435
- data = self.safe_value(response, 'data', {})
2436
- transactions = self.safe_value(data, 'data', [])
2558
+ data = self.safe_dict(response, 'data', {})
2559
+ transactions = self.safe_list(data, 'data', [])
2437
2560
  return self.parse_transactions(transactions, currency, since, limit)
2438
2561
 
2439
- def parse_transaction_status(self, status):
2440
- statuses = {
2562
+ def parse_transaction_status(self, status: Str):
2563
+ statuses: dict = {
2441
2564
  'reviewing': 'pending',
2442
2565
  'pending': 'pending',
2443
2566
  'confirmed': 'ok',
@@ -2445,7 +2568,7 @@ class ascendex(Exchange, ImplicitAPI):
2445
2568
  }
2446
2569
  return self.safe_string(statuses, status, status)
2447
2570
 
2448
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
2571
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2449
2572
  #
2450
2573
  # {
2451
2574
  # "requestId": "wuzd1Ojsqtz4bCA3UXwtUnnJDmU8PiyB",
@@ -2464,7 +2587,7 @@ class ascendex(Exchange, ImplicitAPI):
2464
2587
  # }
2465
2588
  # }
2466
2589
  #
2467
- destAddress = self.safe_value(transaction, 'destAddress', {})
2590
+ destAddress = self.safe_dict(transaction, 'destAddress', {})
2468
2591
  address = self.safe_string(destAddress, 'address')
2469
2592
  tag = self.safe_string(destAddress, 'destTag')
2470
2593
  timestamp = self.safe_integer(transaction, 'time')
@@ -2509,9 +2632,9 @@ class ascendex(Exchange, ImplicitAPI):
2509
2632
  """
2510
2633
  self.load_markets()
2511
2634
  self.load_accounts()
2512
- account = self.safe_value(self.accounts, 0, {})
2635
+ account = self.safe_dict(self.accounts, 0, {})
2513
2636
  accountGroup = self.safe_string(account, 'id')
2514
- request = {
2637
+ request: dict = {
2515
2638
  'account-group': accountGroup,
2516
2639
  }
2517
2640
  response = self.v2PrivateAccountGroupGetFuturesPosition(self.extend(request, params))
@@ -2554,15 +2677,15 @@ class ascendex(Exchange, ImplicitAPI):
2554
2677
  # }
2555
2678
  # }
2556
2679
  #
2557
- data = self.safe_value(response, 'data', {})
2558
- position = self.safe_value(data, 'contracts', [])
2680
+ data = self.safe_dict(response, 'data', {})
2681
+ position = self.safe_list(data, 'contracts', [])
2559
2682
  result = []
2560
2683
  for i in range(0, len(position)):
2561
2684
  result.append(self.parse_position(position[i]))
2562
2685
  symbols = self.market_symbols(symbols)
2563
2686
  return self.filter_by_array_positions(result, 'symbol', symbols, False)
2564
2687
 
2565
- def parse_position(self, position, market: Market = None):
2688
+ def parse_position(self, position: dict, market: Market = None):
2566
2689
  #
2567
2690
  # {
2568
2691
  # "symbol": "BTC-PERP",
@@ -2625,7 +2748,7 @@ class ascendex(Exchange, ImplicitAPI):
2625
2748
  'takeProfitPrice': self.safe_number(position, 'takeProfitPrice'),
2626
2749
  })
2627
2750
 
2628
- def parse_funding_rate(self, contract, market: Market = None):
2751
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
2629
2752
  #
2630
2753
  # {
2631
2754
  # "time": 1640061364830,
@@ -2660,14 +2783,15 @@ class ascendex(Exchange, ImplicitAPI):
2660
2783
  'fundingRate': nextFundingRate,
2661
2784
  'fundingTimestamp': nextFundingRateTimestamp,
2662
2785
  'fundingDatetime': self.iso8601(nextFundingRateTimestamp),
2786
+ 'interval': None,
2663
2787
  }
2664
2788
 
2665
- def fetch_funding_rates(self, symbols: Strings = None, params={}):
2789
+ def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
2666
2790
  """
2667
2791
  fetch the funding rate for multiple markets
2668
2792
  :param str[]|None symbols: list of unified market symbols
2669
2793
  :param dict [params]: extra parameters specific to the exchange API endpoint
2670
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
2794
+ :returns dict[]: a list of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
2671
2795
  """
2672
2796
  self.load_markets()
2673
2797
  symbols = self.market_symbols(symbols)
@@ -2696,19 +2820,18 @@ class ascendex(Exchange, ImplicitAPI):
2696
2820
  # }
2697
2821
  # }
2698
2822
  #
2699
- data = self.safe_value(response, 'data', {})
2700
- contracts = self.safe_value(data, 'contracts', [])
2701
- result = self.parse_funding_rates(contracts)
2702
- return self.filter_by_array(result, 'symbol', symbols)
2823
+ data = self.safe_dict(response, 'data', {})
2824
+ contracts = self.safe_list(data, 'contracts', [])
2825
+ return self.parse_funding_rates(contracts, symbols)
2703
2826
 
2704
- def modify_margin_helper(self, symbol: str, amount, type, params={}):
2827
+ def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
2705
2828
  self.load_markets()
2706
2829
  self.load_accounts()
2707
2830
  market = self.market(symbol)
2708
- account = self.safe_value(self.accounts, 0, {})
2831
+ account = self.safe_dict(self.accounts, 0, {})
2709
2832
  accountGroup = self.safe_string(account, 'id')
2710
2833
  amount = self.amount_to_precision(symbol, amount)
2711
- request = {
2834
+ request: dict = {
2712
2835
  'account-group': accountGroup,
2713
2836
  'symbol': market['id'],
2714
2837
  'amount': amount, # positive value for adding margin, negative for reducing
@@ -2728,19 +2851,30 @@ class ascendex(Exchange, ImplicitAPI):
2728
2851
  'type': type,
2729
2852
  })
2730
2853
 
2731
- def parse_margin_modification(self, data, market: Market = None):
2854
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
2855
+ #
2856
+ # addMargin/reduceMargin
2857
+ #
2858
+ # {
2859
+ # "code": 0
2860
+ # }
2861
+ #
2732
2862
  errorCode = self.safe_string(data, 'code')
2733
2863
  status = 'ok' if (errorCode == '0') else 'failed'
2734
2864
  return {
2735
2865
  'info': data,
2866
+ 'symbol': market['symbol'],
2736
2867
  'type': None,
2868
+ 'marginMode': 'isolated',
2737
2869
  'amount': None,
2870
+ 'total': None,
2738
2871
  'code': market['quote'],
2739
- 'symbol': market['symbol'],
2740
2872
  'status': status,
2873
+ 'timestamp': None,
2874
+ 'datetime': None,
2741
2875
  }
2742
2876
 
2743
- def reduce_margin(self, symbol: str, amount, params={}):
2877
+ def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
2744
2878
  """
2745
2879
  remove margin from a position
2746
2880
  :param str symbol: unified market symbol
@@ -2750,7 +2884,7 @@ class ascendex(Exchange, ImplicitAPI):
2750
2884
  """
2751
2885
  return self.modify_margin_helper(symbol, -amount, 'reduce', params)
2752
2886
 
2753
- def add_margin(self, symbol: str, amount, params={}):
2887
+ def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
2754
2888
  """
2755
2889
  add margin
2756
2890
  :param str symbol: unified market symbol
@@ -2763,7 +2897,9 @@ class ascendex(Exchange, ImplicitAPI):
2763
2897
  def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
2764
2898
  """
2765
2899
  set the level of leverage for a market
2766
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-contract-leverage
2900
+
2901
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-contract-leverage
2902
+
2767
2903
  :param float leverage: the rate of leverage
2768
2904
  :param str symbol: unified market symbol
2769
2905
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2778,9 +2914,9 @@ class ascendex(Exchange, ImplicitAPI):
2778
2914
  market = self.market(symbol)
2779
2915
  if not market['swap']:
2780
2916
  raise BadSymbol(self.id + ' setLeverage() supports swap contracts only')
2781
- account = self.safe_value(self.accounts, 0, {})
2917
+ account = self.safe_dict(self.accounts, 0, {})
2782
2918
  accountGroup = self.safe_string(account, 'id')
2783
- request = {
2919
+ request: dict = {
2784
2920
  'account-group': accountGroup,
2785
2921
  'symbol': market['id'],
2786
2922
  'leverage': leverage,
@@ -2790,7 +2926,9 @@ class ascendex(Exchange, ImplicitAPI):
2790
2926
  def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
2791
2927
  """
2792
2928
  set margin mode to 'cross' or 'isolated'
2793
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-margin-type
2929
+
2930
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-margin-type
2931
+
2794
2932
  :param str marginMode: 'cross' or 'isolated'
2795
2933
  :param str symbol: unified market symbol
2796
2934
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2806,9 +2944,9 @@ class ascendex(Exchange, ImplicitAPI):
2806
2944
  self.load_markets()
2807
2945
  self.load_accounts()
2808
2946
  market = self.market(symbol)
2809
- account = self.safe_value(self.accounts, 0, {})
2947
+ account = self.safe_dict(self.accounts, 0, {})
2810
2948
  accountGroup = self.safe_string(account, 'id')
2811
- request = {
2949
+ request: dict = {
2812
2950
  'account-group': accountGroup,
2813
2951
  'symbol': market['id'],
2814
2952
  'marginType': marginMode,
@@ -2817,7 +2955,7 @@ class ascendex(Exchange, ImplicitAPI):
2817
2955
  raise BadSymbol(self.id + ' setMarginMode() supports swap contracts only')
2818
2956
  return self.v2PrivateAccountGroupPostFuturesMarginType(self.extend(request, params))
2819
2957
 
2820
- def fetch_leverage_tiers(self, symbols: Strings = None, params={}):
2958
+ def fetch_leverage_tiers(self, symbols: Strings = None, params={}) -> LeverageTiers:
2821
2959
  """
2822
2960
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
2823
2961
  :param str[]|None symbols: list of unified market symbols
@@ -2854,11 +2992,11 @@ class ascendex(Exchange, ImplicitAPI):
2854
2992
  # ]
2855
2993
  # }
2856
2994
  #
2857
- data = self.safe_value(response, 'data')
2995
+ data = self.safe_list(response, 'data', [])
2858
2996
  symbols = self.market_symbols(symbols)
2859
2997
  return self.parse_leverage_tiers(data, symbols, 'symbol')
2860
2998
 
2861
- def parse_market_leverage_tiers(self, info, market: Market = None):
2999
+ def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
2862
3000
  """
2863
3001
  :param dict info: Exchange market response for 1 market
2864
3002
  :param dict market: CCXT market
@@ -2886,15 +3024,16 @@ class ascendex(Exchange, ImplicitAPI):
2886
3024
  # ]
2887
3025
  # }
2888
3026
  #
2889
- marginRequirements = self.safe_value(info, 'marginRequirements', [])
2890
- id = self.safe_string(info, 'symbol')
2891
- market = self.safe_market(id, market)
3027
+ marginRequirements = self.safe_list(info, 'marginRequirements', [])
3028
+ marketId = self.safe_string(info, 'symbol')
3029
+ market = self.safe_market(marketId, market)
2892
3030
  tiers = []
2893
3031
  for i in range(0, len(marginRequirements)):
2894
3032
  tier = marginRequirements[i]
2895
3033
  initialMarginRate = self.safe_string(tier, 'initialMarginRate')
2896
3034
  tiers.append({
2897
3035
  'tier': self.sum(i, 1),
3036
+ 'symbol': self.safe_symbol(marketId, market, None, 'contract'),
2898
3037
  'currency': market['quote'],
2899
3038
  'minNotional': self.safe_number(tier, 'positionNotionalLowerBound'),
2900
3039
  'maxNotional': self.safe_number(tier, 'positionNotionalUpperBound'),
@@ -2924,9 +3063,9 @@ class ascendex(Exchange, ImplicitAPI):
2924
3063
  # ]
2925
3064
  # }
2926
3065
  #
2927
- blockChains = self.safe_value(fee, 'blockChain', [])
3066
+ blockChains = self.safe_list(fee, 'blockChain', [])
2928
3067
  blockChainsLength = len(blockChains)
2929
- result = {
3068
+ result: dict = {
2930
3069
  'info': fee,
2931
3070
  'withdraw': {
2932
3071
  'fee': None,
@@ -2955,14 +3094,16 @@ class ascendex(Exchange, ImplicitAPI):
2955
3094
  def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
2956
3095
  """
2957
3096
  fetch deposit and withdraw fees
2958
- :see: https://ascendex.github.io/ascendex-pro-api/#list-all-assets
3097
+
3098
+ https://ascendex.github.io/ascendex-pro-api/#list-all-assets
3099
+
2959
3100
  :param str[]|None codes: list of unified currency codes
2960
3101
  :param dict [params]: extra parameters specific to the exchange API endpoint
2961
3102
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
2962
3103
  """
2963
3104
  self.load_markets()
2964
3105
  response = self.v2PublicGetAssets(params)
2965
- data = self.safe_value(response, 'data')
3106
+ data = self.safe_list(response, 'data')
2966
3107
  return self.parse_deposit_withdraw_fees(data, codes, 'assetCode')
2967
3108
 
2968
3109
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
@@ -2977,18 +3118,17 @@ class ascendex(Exchange, ImplicitAPI):
2977
3118
  """
2978
3119
  self.load_markets()
2979
3120
  self.load_accounts()
2980
- account = self.safe_value(self.accounts, 0, {})
3121
+ account = self.safe_dict(self.accounts, 0, {})
2981
3122
  accountGroup = self.safe_string(account, 'id')
2982
3123
  currency = self.currency(code)
2983
- amount = self.currency_to_precision(code, amount)
2984
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
3124
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
2985
3125
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
2986
3126
  toId = self.safe_string(accountsByType, toAccount, toAccount)
2987
3127
  if fromId != 'cash' and toId != 'cash':
2988
3128
  raise ExchangeError(self.id + ' transfer() only supports direct balance transfer between spot and swap, spot and margin')
2989
- request = {
3129
+ request: dict = {
2990
3130
  'account-group': accountGroup,
2991
- 'amount': amount,
3131
+ 'amount': self.currency_to_precision(code, amount),
2992
3132
  'asset': currency['id'],
2993
3133
  'fromAccount': fromId,
2994
3134
  'toAccount': toId,
@@ -2997,7 +3137,7 @@ class ascendex(Exchange, ImplicitAPI):
2997
3137
  #
2998
3138
  # {"code": "0"}
2999
3139
  #
3000
- transferOptions = self.safe_value(self.options, 'transfer', {})
3140
+ transferOptions = self.safe_dict(self.options, 'transfer', {})
3001
3141
  fillResponseFromRequest = self.safe_bool(transferOptions, 'fillResponseFromRequest', True)
3002
3142
  transfer = self.parse_transfer(response, currency)
3003
3143
  if fillResponseFromRequest:
@@ -3007,11 +3147,11 @@ class ascendex(Exchange, ImplicitAPI):
3007
3147
  transfer['currency'] = code
3008
3148
  return transfer
3009
3149
 
3010
- def parse_transfer(self, transfer, currency: Currency = None):
3150
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
3011
3151
  #
3012
3152
  # {"code": "0"}
3013
3153
  #
3014
- status = self.safe_integer(transfer, 'code')
3154
+ status = self.safe_string(transfer, 'code')
3015
3155
  currencyCode = self.safe_currency_code(None, currency)
3016
3156
  return {
3017
3157
  'info': transfer,
@@ -3025,15 +3165,17 @@ class ascendex(Exchange, ImplicitAPI):
3025
3165
  'status': self.parse_transfer_status(status),
3026
3166
  }
3027
3167
 
3028
- def parse_transfer_status(self, status):
3029
- if status == 0:
3168
+ def parse_transfer_status(self, status: Str) -> Str:
3169
+ if status == '0':
3030
3170
  return 'ok'
3031
3171
  return 'failed'
3032
3172
 
3033
3173
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3034
3174
  """
3035
3175
  fetch the history of funding payments paid and received on self account
3036
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#funding-payment-history
3176
+
3177
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#funding-payment-history
3178
+
3037
3179
  :param str [symbol]: unified market symbol
3038
3180
  :param int [since]: the earliest time in ms to fetch funding history for
3039
3181
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -3047,9 +3189,9 @@ class ascendex(Exchange, ImplicitAPI):
3047
3189
  paginate, params = self.handle_option_and_params(params, 'fetchFundingHistory', 'paginate')
3048
3190
  if paginate:
3049
3191
  return self.fetch_paginated_call_incremental('fetchFundingHistory', symbol, since, limit, params, 'page', 25)
3050
- account = self.safe_value(self.accounts, 0, {})
3192
+ account = self.safe_dict(self.accounts, 0, {})
3051
3193
  accountGroup = self.safe_string(account, 'id')
3052
- request = {
3194
+ request: dict = {
3053
3195
  'account-group': accountGroup,
3054
3196
  }
3055
3197
  market = None
@@ -3077,8 +3219,8 @@ class ascendex(Exchange, ImplicitAPI):
3077
3219
  # }
3078
3220
  # }
3079
3221
  #
3080
- data = self.safe_value(response, 'data', {})
3081
- rows = self.safe_value(data, 'data', [])
3222
+ data = self.safe_dict(response, 'data', {})
3223
+ rows = self.safe_list(data, 'data', [])
3082
3224
  return self.parse_incomes(rows, market, since, limit)
3083
3225
 
3084
3226
  def parse_income(self, income, market: Market = None):
@@ -3102,19 +3244,21 @@ class ascendex(Exchange, ImplicitAPI):
3102
3244
  'amount': self.safe_number(income, 'paymentInUSDT'),
3103
3245
  }
3104
3246
 
3105
- def fetch_margin_modes(self, symbols: List[str] = None, params={}) -> MarginModes:
3247
+ def fetch_margin_modes(self, symbols: Strings = None, params={}) -> MarginModes:
3106
3248
  """
3107
3249
  fetches the set margin mode of the user
3108
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
3250
+
3251
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
3252
+
3109
3253
  :param str[] [symbols]: a list of unified market symbols
3110
3254
  :param dict [params]: extra parameters specific to the exchange API endpoint
3111
3255
  :returns dict: a list of `margin mode structures <https://docs.ccxt.com/#/?id=margin-mode-structure>`
3112
3256
  """
3113
3257
  self.load_markets()
3114
3258
  self.load_accounts()
3115
- account = self.safe_value(self.accounts, 0, {})
3259
+ account = self.safe_dict(self.accounts, 0, {})
3116
3260
  accountGroup = self.safe_string(account, 'id')
3117
- request = {
3261
+ request: dict = {
3118
3262
  'account-group': accountGroup,
3119
3263
  }
3120
3264
  response = self.v2PrivateAccountGroupGetFuturesPosition(self.extend(request, params))
@@ -3161,7 +3305,7 @@ class ascendex(Exchange, ImplicitAPI):
3161
3305
  marginModes = self.safe_list(data, 'contracts', [])
3162
3306
  return self.parse_margin_modes(marginModes, symbols, 'symbol')
3163
3307
 
3164
- def parse_margin_mode(self, marginMode, market=None) -> MarginMode:
3308
+ def parse_margin_mode(self, marginMode: dict, market=None) -> MarginMode:
3165
3309
  marketId = self.safe_string(marginMode, 'symbol')
3166
3310
  marginType = self.safe_string(marginMode, 'marginType')
3167
3311
  margin = 'cross' if (marginType == 'crossed') else 'isolated'
@@ -3171,19 +3315,21 @@ class ascendex(Exchange, ImplicitAPI):
3171
3315
  'marginMode': margin,
3172
3316
  }
3173
3317
 
3174
- def fetch_leverages(self, symbols: List[str] = None, params={}) -> Leverages:
3318
+ def fetch_leverages(self, symbols: Strings = None, params={}) -> Leverages:
3175
3319
  """
3176
3320
  fetch the set leverage for all contract markets
3177
- :see: https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
3321
+
3322
+ https://ascendex.github.io/ascendex-futures-pro-api-v2/#position
3323
+
3178
3324
  :param str[] [symbols]: a list of unified market symbols
3179
3325
  :param dict [params]: extra parameters specific to the exchange API endpoint
3180
3326
  :returns dict: a list of `leverage structures <https://docs.ccxt.com/#/?id=leverage-structure>`
3181
3327
  """
3182
3328
  self.load_markets()
3183
3329
  self.load_accounts()
3184
- account = self.safe_value(self.accounts, 0, {})
3330
+ account = self.safe_dict(self.accounts, 0, {})
3185
3331
  accountGroup = self.safe_string(account, 'id')
3186
- request = {
3332
+ request: dict = {
3187
3333
  'account-group': accountGroup,
3188
3334
  }
3189
3335
  response = self.v2PrivateAccountGroupGetFuturesPosition(self.extend(request, params))
@@ -3230,7 +3376,7 @@ class ascendex(Exchange, ImplicitAPI):
3230
3376
  leverages = self.safe_list(data, 'contracts', [])
3231
3377
  return self.parse_leverages(leverages, symbols, 'symbol')
3232
3378
 
3233
- def parse_leverage(self, leverage, market=None) -> Leverage:
3379
+ def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
3234
3380
  marketId = self.safe_string(leverage, 'symbol')
3235
3381
  leverageValue = self.safe_integer(leverage, 'leverage')
3236
3382
  marginType = self.safe_string(leverage, 'marginType')
@@ -3295,7 +3441,7 @@ class ascendex(Exchange, ImplicitAPI):
3295
3441
  url = self.urls['api']['rest'] + url
3296
3442
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
3297
3443
 
3298
- def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
3444
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
3299
3445
  if response is None:
3300
3446
  return None # fallback to default error handler
3301
3447
  #